(Python)__new__方法返回的不是类实例

7

是否可以实现当创建一个类的新对象时,返回的不是对象本身?如果可以,如何实现呢?

假设我想让每个新创建的对象都作为包含其自身的列表。

>> class A:
      *magic*

>> a = A()
>> print a

[<__main__.A instance at 0x01234567>]

也许可以通过某种方式重写__new__方法来实现,但是怎么做呢?
1个回答

10

是的,__new__ 可以返回除了新实例之外的其他东西:

class A(object):
    def __new__(cls, *args, **kw):
        instance = super(A, cls).__new__(cls, *args, **kw)
        return [instance]

演示:

>>> class A(object):
...     def __new__(cls, *args, **kw):
...         instance = super(A, cls).__new__(cls, *args, **kw)
...         return [instance]
... 
>>> A()
[<__main__.A object at 0x10f33f390>]
注意,如果返回的对象不是相同类型(因此isinstance(returned_value, A)False),则不会调用__init__;这意味着自定义的A.__init__()永远不会在这里调用!需要显式地调用它:
class A(object):
    def __new__(cls, *args, **kw):
        instance = super(A, cls).__new__(cls, *args, **kw)
        if hasattr(cls, '__init__'):
            instance.__init__(*args, **kw)            
        return [instance]

这是哪个Python版本?它不能在Python 2.7.2上运行。 - Simeon Visser
1
@SimeonVisser:那是Python 3;已更新以在Python 2上工作;__new__仅适用于新样式对象。 - Martijn Pieters
这样做是可以的,但如果类中还包含__init__方法,则在创建对象时不会调用它。如何使其正常工作? - user2649762
对的,在__new__的返回值上调用__init__;在那种情况下,你必须显式地__new__中调用它。 - Martijn Pieters
等等,等等,所以类的__init__会在列表上调用吗?测试表明不会,但是Python如何判断它是否是有效的返回值来初始化? - user2649762
@user2649762:啊,确实,type_call将会再次检查返回的对象是否为相同类型。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接