我想测试一个对象是否是一个类的实例,并且只测试这个类(没有子类).我可以这样做:
obj.__class__ == Foo
obj.__class__ is Foo
type(obj) == Foo
type(obj) is Foo
Run Code Online (Sandbox Code Playgroud)
是否有理由选择一个而不是另一个?(业绩差异,陷阱等)
换句话说:a)使用__class__和type(x)?之间有什么实际区别吗?b)类对象总是可以安全地进行比较is吗?
更新:感谢大家的反馈.我仍然对类对象是否是单身人士感到困惑,我的常识说他们是,但是很难得到确认(尝试谷歌搜索"python","class"和"unique"或"singleton") .
我还要澄清一点,根据我的特殊需求,"更便宜"的解决方案才是最好的,因为我正在尝试优化一些专业课程中的大部分(几乎达到了理智的程度)要做的是删除Python并在C)中开发该特定模块.但问题背后的原因是为了更好地理解语言,因为它的某些功能对于我来说很容易找到这些信息.这就是为什么我让讨论延伸一点而不是解决__class__ is,所以我可以听到更有经验的人的意见.到目前为止,它已经非常富有成效!
我进行了一项小测试,以测试4种替代方案的性能.分析器结果是:
Python PyPy (4x)
type() is 2.138 2.594
__class__ is 2.185 2.437
type() == 2.213 2.625
__class__ == 2.271 2.453
Run Code Online (Sandbox Code Playgroud)
不出所料,is表现优于==所有情况.type()在Python中表现更好(2%更快)并且__class__在PyPy中表现更好(快6%).有趣的是,__class__ ==在PyPy 中表现更好type() is.
更新2:很多人似乎并不理解我所说的"一个类是一个单身人士",所以我将用一个例子说明:
>>> class Foo(object): pass
...
>>> X = Foo
>>> class Foo(object): pass
... …Run Code Online (Sandbox Code Playgroud) type(obj)和之间有什么区别obj.__class__?有可能type(obj) is not obj.__class__吗?
我想编写一个在提供的对象上一般工作的函数,使用与另一个参数相同类型的默认值1.下面的#1或#2哪个变体会做正确的事情?
def f(a, b=None):
if b is None:
b = type(a)(1) # #1
b = a.__class__(1) # #2
Run Code Online (Sandbox Code Playgroud) 我遇到了一个python问题.我想用来type()找出我正在使用的变量类型.代码看起来与此类似:
class Foo():
array=[ myField(23),myField(42),myField("foo"), myField("bar")]
def returnArr(self):
for i in self.array:
print type(i)
if __name__ == "__main__":
a=Foo()
a.returnArr()
Run Code Online (Sandbox Code Playgroud)
编辑:myField()是我定义的类.
当我要求type()时,我得到: <type 'instance'>现在根据1,这是因为我使用了一个类元素并要求type()它.现在,我需要的是:<type 'int'>对于例如:myField(42)与<type 'str'>对myField(foo).我怎么能实现这一点?
编辑:
def __init__(self, name, default, fmt="H"):
self.name = name
if fmt[0] in "@=<>!":
self.fmt = fmt
else:
self.fmt = "!"+fmt
self.default = self.any2i(None,default)
self.sz = struct.calcsize(self.fmt)
self.owners = []
Run Code Online (Sandbox Code Playgroud)
代码取自scapy,我尝试调整它.
我正在尝试使用OOP python,我不确定__repr__函数继承.由于父类函数看起来像这样:
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format("Class name", self._param))
Run Code Online (Sandbox Code Playgroud)
我想知道是否更好地使用通用方法(也适用于子类),如下所示:
def __repr__(self):
'''Returns representation of the object'''
return("{}({!r})".format(self.__class__.__name__, self._param))
Run Code Online (Sandbox Code Playgroud)
或者如果在每个班级中覆盖该功能是一个好习惯.
另外,请忽略编码部分,因为我将它留在后面.
从这里:
Run Code Online (Sandbox Code Playgroud)super( [ type [ , object-or-type ]] )返回一个代理对象,该方法将方法调用委托给父类或兄弟类
type.这对于访问已在类中重写的继承方法很有用.搜索顺序与使用的搜索顺序相同,getattr()只是type跳过了自身.如果省略第二个参数,则返回的超级对象是未绑定的.
如果第二个参数是一个对象,则
isinstance(obj, type)必须为true.如果第二个参数是一个类型,则
issubclass(type2, type)必须为true(这对于classmethods很有用).
如果我是正确的,则类型是类,类是类型.类是一个对象,因此类型也是一个对象.当第二个参数是一个类型的对象时,为什么引用会区分这两种情况?
当第二个参数是一个类型时,为什么issubclass(type2, type)
要求为真?
super分别在三种情况下返回的超级对象的类型是什么?或者你如何确定返回的超级对象的类型super?
当第二个参数是一个对象时,因为"搜索顺序与getattr()除了type自身被跳过之外的搜索顺序相同",我猜测super函数返回的superobject的类型应该是第一个参数的任何祖先类的子类type,但我发现它实际上不是通过测试issubclass.所以我误解了什么?
实现__repr__了一类Foo有成员变量x和y,是有办法来自动填充字符串?不起作用的示例:
class Foo(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Foo({})".format(**self.__dict__)
>>> foo = Foo(42, 66)
>>> print(foo)
IndexError: tuple index out of range
Run Code Online (Sandbox Code Playgroud)
而另一个:
from pprint import pprint
class Foo(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Foo({})".format(pprint(self.__dict__))
>>> foo = Foo(42, 66)
>>> print(foo)
{'x': 42, 'y': 66}
Foo(None)
Run Code Online (Sandbox Code Playgroud)
是的我可以将方法定义为
def __repr__(self):
return "Foo({x={}, y={}})".format(self.x, self.x)
Run Code Online (Sandbox Code Playgroud)
但是当有许多成员变量时,这会变得乏味.