在__new__内调用的方法

时间:2015-08-17 12:27:43

标签: python

我想创建一个在启动时返回int的类,如下所示:

r = Foo(10)
print r # 1000

我知道你可以通过覆盖__new__方法来做到这一点。但是我需要它在__new__方法中执行其他类函数,我该怎么做?

到目前为止,我有:

class Foo(object):
    def __new__(cls, i):
        cls.i = i
        return cls.foo_fun()

    def foo_fun(self):
        return self.i * 100
print Foo(5)

我得到的错误:

Traceback (most recent call last):
return cls.foo_fun()
TypeError: unbound method foo_fun() must be called with Foo instance as first argument (got nothing instead)

1 个答案:

答案 0 :(得分:3)

您的__new__工厂方法中没有实例(实际上是静态的)。你没有 self来打电话。使用另一种静态或类方法:

class Foo(object):
    def __new__(cls, i):
        return cls.foo_fun(i)

    @staticmethod
    def foo_fun(i):
        return i * 100

print Foo(5)

设置cls.i不是线程安全的,因为该状态在所有__new__个调用之间共享;最好将值作为参数传递给另一个方法。

但是,你在这里滥用课程;你永远不会创建这个类的实例,没有办法在isinstance()类型检查等中使用该类。只需使用工厂函数:

def foo(i):
    return i * 100

如果你真的想要成为int的子类,你仍然需要创建一个类的实际实例来返回:

class Foo(int):
    def __new__(cls, i):
        i = int(i)  # ensure you have an actual integer first
        value = cls.foo_fun(i)
        return super(Foo, cls).__new__(cls, value)

    @staticmethod
    def foo_fun(i):
        return i * 100

以上继承自int,处理参数不是整数的情况(like“42”`,一个可转换为整数的字符串)并返回类的实例。 / p>

演示:

>>> class Foo(int):
...     def __new__(cls, i):
...         i = int(i)  # ensure you have an actual integer first
...         value = cls.foo_fun(i)
...         return super(Foo, cls).__new__(cls, value)
...     @staticmethod
...     def foo_fun(i):
...         return i * 100
... 
>>> f = Foo(42)
>>> f
4200
>>> isinstance(f, Foo)
True
>>> Foo("42")  # non-integer input works too
4200