2016-11-21 14 views
1

私はクラスfibを持っています。それは__iter____next__を実装します。それは反復可能であり、それ自身の反復子でもあります。クラスが反復可能かどうかの確認

class fib(object): 
    def __init__(self): 
     self.prev = 0 
     self.curr = 1 

    def __iter__(self): 
     return self 

    def __next__(self): 
     value = self.curr 
     self.curr += self.prev 
     self.prev = value 
     return value 


from collections import Iterable 

print(isinstance(fib, Iterable)) 

print文はFalseを返し、私はそれは、オブジェクトが反復可能であるかどうかの確認True

+1

'fib'はインスタンスではなく*クラス*です。したがって、サブクラスチェック 'issubclass(fib、Iterable)'を使用します。または、インスタンスを最初に作成する: 'isinstance(fib()、Iterable)' - 小文字でクラス名を始めるために得られるもの); – poke

+0

'fib'は反復不可能です。 'fib'はインスタンスが反復可能なクラスです。 「ファイブ」自体を反復しようとすると、ハンバーガーのコンセプトを食べようとするようなものになります。 – user2357112

答えて

4

を返すことを期待するあなたがやったように行われ、正しくある:

isinstance(obj, collections.Iterable) 

ここでの問題はclassisinstanceに、インスタンスではないことです。もちろん、ケース

type(fib).__iter__ # AttributeError 

これではありません:isinstanceは先に行くとtype(fib)が定義され__iter__方法をしているかどうかをチェックしますので、それはFalseです。 type(fib)はメソッドを定義していないtypeです。

あなたがそれにインスタンスを指定した場合、それは正しくTrueを出力します。

isinstance(fib(), Iterable) # True 

type(fib())で探して、それはfib.__iter__がありますので。指摘する

issubclass(fib, Iterable) # True 

2つの余分なマイナーなもの:

  • としてobjectを使用しissubclassからfibを供給する代わりに

    は、代わりに、最初の引数としてクラスをとる、という同様のチェックを行い、明示的な基底クラスはPython 3では不要です(ただしPy2とPy3の両方で動作するコードを開発している場合は良いことです)

  • PEP 8によると、クラス名はCapWords規約に準拠する必要がありますので、fibの名前はFibとするのが理想です。
関連する問題