检查类是否可迭代

时间:2016-11-21 20:23:37

标签: python class python-3.x iterable

我有一个课程__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)) 。它是一个可迭代的,也是它自己的迭代器。

False

print语句返回True,我希望它返回import UIKit class ViewController: UIViewController, UIScrollViewDelegate { @IBOutlet weak var mainScroll: UIScrollView! let stackHeight: CGFloat = 30.0 override func viewDidLoad() { super.viewDidLoad() mainScroll.delegate = self print("----- viewDidLoad -----") let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.swiped(_:))) swipeDown.direction = UISwipeGestureRecognizerDirection.Down self.view.addGestureRecognizer(swipeDown) let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.swiped(_:))) swipeUp.direction = UISwipeGestureRecognizerDirection.Up self.view.addGestureRecognizer(swipeUp) } func swiped(gesture: UIGestureRecognizer) { if let swipeGesture = gesture as? UISwipeGestureRecognizer { switch swipeGesture.direction { case UISwipeGestureRecognizerDirection.Down: print("DOWN") if (mainScroll.contentOffset.y >= stackHeight) { mainScroll.contentOffset.y = mainScroll.contentOffset.y - stackHeight } case UISwipeGestureRecognizerDirection.Up: print("UP \(mainScroll.contentOffset.y)") if (mainScroll.contentOffset.y <= stackHeight*16 ) { mainScroll.contentOffset.y = mainScroll.contentOffset.y+stackHeight } default: break } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }

1 个答案:

答案 0 :(得分:8)

检查对象是否可迭代是正确的,正如您所做的那样,执行:

isinstance(obj, collections.Iterable)

此处的问题是您向class提供isinstance而不是实例。它是False,因为isinstance会继续检查type(fib)是否定义了__iter__方法:

type(fib).__iter__  # AttributeError

当然,情况并非如此。 type(fib)type,它没有定义__iter__方法。

如果您为其提供实例,则会正确打印True

isinstance(fib(), Iterable)  # True

因为查看type(fib())会找到fib.__iter__

或者,将fib提供给issubclass会执行类似的检查,而是将一个类作为第一个参数:

issubclass(fib, Iterable)    # True

要指出两件额外的小事:

  • 在Python object中不需要使用3作为显式基类(但是,如果您正在开发在Py2和Py3上运行的代码,那么这是一件好事。(参见Python class inherits object了解更多信息。)
  • 根据PEP 8,类名应遵循CapWords惯例,因此fib理想情况下应命名为Fib