与tee对象有关

时间:2016-03-09 01:01:05

标签: python tee isinstance

作为记忆机制的一部分,我有一个生成器,我tee,我需要用isinstnace检查它的类型。

>>> gen = (i for i in range(5))
>>> one, two = itertools.tee(gen, 2)

然后

>>> type(one), type(two)
(itertools.tee, itertools.tee)

正如所料,但

>>> isinstance(one, itertools.tee)
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

那么tee的实例是什么?

5 个答案:

答案 0 :(得分:4)

itertools.tee是一个函数,而不是一个类(请参阅type(itertools.tee))。它返回tee类的实例(有点令人困惑)的对象,但该类在itertools命名空间中不可用。我只是使用type()从一个实例中获取它。如果您没有方便的实例,请创建一个。这似乎是获取tee类型的最小代码量:

TeeType = type(itertools.tee(())[0])

看来tee始终为每次调用使用相同的类。

答案 1 :(得分:4)

tee是一个返回Python使用的内部实现类型的函数。一般来说,它应该是tee或任何其他iterator / generator类型。

那就是说,如果你真的需要输入这样的测试,你可以这样做,你只需要像检查类型那样导出tee实例的“真实”类型,方法是使用type。例如,要将tee实例的类型存储在名为Tee的变量中,您需执行以下操作:

Tee = type(itertools.tee(())[0])

调用tee来获取实例,然后使用type获取他们的类。

这是记录的唯一可移植方式;实际类型涉及(正在实现内部)从发布到发布的变化;在Python 3.5中,您可以将原始类型作为itertools._tee访问,但显然在您的版本中,它不会像那样暴露。

答案 2 :(得分:2)

isinstance用于检查是否有东西说它是鸭子,无论它是否是鸭子。

要回答您的直接问题,isinstance.tee是一种方法,而不是类,或类型的类型或元组:

>>> type(itertools.tee)
<class 'builtin_function_or_method'>

(事实上,在我的python版本中,类已经从选项列表中删除了)。 Python是一种“鸭型”语言。基本上,为了让'isinstance'说某事是另一件事的一个实例,它必须以某种方式从它继承。

示例:

>>> type(str)
<class 'type'>
>>> s = "foo"
>>> isinstance(s,str)
True
>>> class myString(str): #myString inherits from str (a type)
...   def __init__(self,s):
...     super().__init__()
... 
>>> s = myString("foo")
>>> s
'foo'
>>> isinstance(s,str) 
True

首先,这些继承的基类应该(尽可能)基类型或抽象基类。为什么是这样?好吧,Python的开发人员希望避免我们有一百万个新用户类型的情况,例如人们开始检查的FooString和BarInt。这应该避免。

ABC提供了一种允许对象说它是某种东西的方式,比如Integral或String,而不必(必然)必须是一个字符串。

但是,Python的duck typing是建立在实现协议之上的。协议由类中的一个或多个“特殊”(或魔术或dunder)方法定义。确定类的哪些特殊方法可以使用dir(myObj)完成:

>>> dir(itertools.tee)
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']

或者,甚至更好,在可能的情况下,只是尝试用它做一些事情,如果它失败了,你知道它不是一个鸭子:

try: duck(something)
except: print("Not a duck!")

答案 3 :(得分:2)

我们假设我们定义了一个班级MyClass

class MyClass(object):
    pass

然后我们定义一个覆盖该类的函数:

def MyClass(x=MyClass):
    return x()

如果我们调用该函数,我们将获得原始MyClass的实例:

>>> instance = MyClass()
>>> type(instance)
<class '__main__.MyClass'>

看起来MyClass是一个类,因为它的返回值的类型具有相同的名称,但请看一下:

>>> type(MyClass)
<type 'function'>

MyClass是一个返回MyClass实例的函数,但它们是不同的。与tee完全相同。 tee是一个返回tee实例的函数。当您看到该实例的类型tee时,您实际上并未检查类或类型;你正在检查一个功能。 isinstance()不会允许,因此错误。获得该类的方法是创建一个实例:

>>> tee = type(itertools.tee(())[0])
>>> isinstance(one, tee)
True

答案 4 :(得分:-1)

tee是一个返回非itertools.tee实例的函数。检查实例的类名的一种方法是(有点hacky):

>> one.__class__.__name__ == "tee"
True