9

__class__在类中创建新实例是个好主意吗?

以下代码是执行此操作的示例:

from collections import namedtuple

_Position = namedtuple('Position', ['x', 'y'])
class Position(_Position):
    def __add__(self, other):
        return __class__(self.x + other.x, self.y + other.y)

对我来说,使用实际的类名听起来像是重复的代码。如果类的名称发生更改,我必须在所有情况下都更改它,即使现代 IDE 可以为您做到这一点。

顺便提一句。什么样的变量是__class__?您不应该只能使用 访问它self.吗?

4

1 回答 1

16

为了支持 的零参数形式,编译器会在类方法中使用或正在使用时super()添加对类的隐式引用。请参阅创建类对象__class__super()

您找到的示例代码 (ab) 使用这个小事实来创建Position添加时的新实例。

就个人而言,我会type(self)改用它,因为这是确定任何对象的类型或类的正确 API 方法。type(self)self.__class__在适当的地方使用:

def __add__(self, other):
    return type(self)(self.x + other.x, self.y + other.y)

如果您想支持子类化,这是一个好主意。的任何子Position类在添加在一起时都将返回正确的子类类型。Using__class__不会这样做,因为它总是指向Position,即使对于子类:

>>> class Foo:
...     def method(self):
...         print(__class__)
...         print(type(self))
... 
>>> class Bar(Foo):
...     pass
... 
>>> Bar().method()
<class '__main__.Foo'>
<class '__main__.Bar'>

当然,如果这是您一直以来的意图(绕过子类),我仍然更喜欢使用显式类名而不是 using __class__; 显式优于隐式。

于 2013-01-01T17:08:10.670 回答