2015-08-17 3 views
0

Я хотел бы создать класс, который возвращает Int, когда инициируется, например, так:методы называются в __new__

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) 
+0

ли изменить его на 'обратный cls.foo_fun (само)' (или 'foo_fun (ЦБС)') работать? –

+0

Обратите внимание, что просто использование 'cls' вместо' self' не делает это методом класса, вам нужно будет использовать ['classmethod'] (https://docs.python.org/2/library/functions. html # classmethod) decorator (В этом случае я не думаю, что '__new__' может быть методом класса). –

+4

Что вы на самом деле пытаетесь достичь? Почему бы не использовать заводскую функцию? – dhke

ответ

3

У вас нет экземпляра в методе __new__ фабрики (который является статическим, на самом деле). У вас нет есть a 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» `, строка конвертируется в целое число) и возвращает экземпляр вашего класса.

Демо:

>>> 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 
Смежные вопросы