2016-04-16 3 views
3

Я работаю через это tutorial. Я работаю над этим итеративно. На данный момент у меня есть следующий класс Binary:ТипError: __init __() должен возвращать None, not 'int'

class Binary: 
    def __init__(self,value): 
     self.value = str(value) 
     if self.value[:2] == '0b': 
      print('a binary!') 
      self.value= int(self.value, base=2) 
     elif self.value[:2] == '0x': 
      print('a hex!') 
      self.value= int(self.value, base=16) 
     else: 
      print(self.value) 
     return int(self.value) 

Я бегу через набор тестов с использованием pytest, в том числе:

def test_binary_init_hex(): 
     binary = Binary(0x6) 
     assert int(binary) == 6 
     E TypeError: int() argument must be a string or a number, not 'Binary' 

я задал вопрос об этом TypeError: int() argument must be a string or a number, not 'Binary' и на основе ответа изменил код так, как указано выше. Теперь, когда я запускаю набор тестов с использованием pytest, все тесты неудачу и ошибка:

 TypeError: __init__() should return None, not 'int' 

Почему существует проблема?

+3

Этот ответ не возвращает 'int' из' __init__'. Он определяет метод '__int__', используемый для числового преобразования. –

+0

'__init __()' используется для инициализации объектов, поэтому не используйте его таким образом, но используйте отдельный метод для этой более поздней цели. –

+0

Почему это даже класс, а не только функция? – iAdjunct

ответ

2

В documentation состояния:

"Поскольку новый() и Инициализационные() работают вместе в строительстве объектов (новый(), чтобы создать его, и инициализации(), чтобы настроить его), не без Отсутствует значение не может быть возвращен инициализации(); делать это вызовет TypeError быть поднят во время выполнения "

так что удалить. return заявление и поместить его в __int__ метод в вашем классе:

def __int__(self): 
    return int(self.value) 
2

__init__ называется, после того, как экземпляр был создан с

obj = SomeClass() 

Так что теперь способ присвоить любое возвращаемое значение переменной , поэтому __init__ не должен возвращать ничего (кроме неявного None).

Для прохождения теста объект должен иметь магический метод __int__, который вызывается, когда используется функция int.

+0

Спасибо Даниэлю, что ответил на другой вопрос, который у меня был, что такое метод '__int__'? Итак, если я правильно понял, что '__int__' переопределяет регулярную встроенную функцию int()? – user61629

2

__init__ Не может вернуть ничего, кроме None. Это потому, что это инициализатор экземпляра, созданного __new__, оба из которых называются неявно, когда вы вызываете вызываемый класс. Следовательно, если вы пытаетесь вернуть что-либо от себя, возникает исключение TypeError.

Возможные решения: реорганизовать ваш код на методы или @property и использовать их позже. Если вам нужны какие-то более смелые метатеки для проверки.

2

__init__ инициализирует экземпляр класса (в вашем случае экземпляр Binary). Экземпляр класса представляет собой конкретную вещь конкретного типа.

В вашем случае, вы, кажется, не использовать его в качестве типа из вещи но вместо того, чтобы как утилита, которая интеллектуально преобразует числа.Вы должны вместо этого, вероятно, просто сделать его функцию:

def binary (value) : 
    value = str(value) 
    if self.value[:2] == '0b': 
     print('a binary!') 
     value = int(value, base=2) 
    elif self.value[:2] == '0x': 
     print('a hex!') 
     value = int(value, base=16) 
    else: 
     print(value) 
    return int(value) 
+0

Спасибо, вы, вероятно, правы, но я слежу за сообщением в блоге, чтобы научить себя некоторому oop – user61629

+0

Но вам не хватает точки ООП, потому что то, что вы делаете, не является объектом. – iAdjunct

3

Прежде был предоставлен какой-либо ответ, я заметил, что __init__() используется для инициализации объектов и, таким образом, вы не должны возвращать никакого значения в нем. Но странно видеть, что некоторые из вышеперечисленных ответов были высказаны не для того, чтобы вернуть значения в пределах ut, но их решение не уважает то, что они сказали. Только @CPanda не сделал ничего противоположного тому, что он сказал. Вот почему я хочу highlight this again в ответ:

Called after the instance has been created (by __new__()), but before it is returned to the caller. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class's __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: BaseClass.__init__(self, [args...]).

Because __new__() and __init__() work together in constructing objects (new() to create it, and __init__() to customise it), no non-None value may be returned by __init__() ; doing so will cause a TypeError to be raised at runtime.

Так не возвращают значения, используя __init__()!

Другой вещь, которую я хочу добавить, даже если это не упоминается AFAIK в Python Enhancement Proposals, лично я никогда не использую __init__() для печати сообщений с использованием print''/print(''). Единственными сообщениями, которые я печатаю в __init__(), являются сообщения, связанные с поднятыми сообщениями об ошибках исключения в таких формах, как raise ValueError() (для получения дополнительной информации см. Built-in Exceptions)

Смежные вопросы