Подтвердить что ты не робот

Полезность def __init __ (self)?

Я новичок в python и заметил эти сообщения: Python __init__ и сам, что они делают? и классы Python без использования def __init __ (self)

Тем не менее, после разговора с ним я заметил, что эти два класса дают, по-видимому, эквивалентные результаты -
class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

(от этот вопрос)

и

class B(object):
    x = 'Hello'
    def method_b(self,foo):
        print self.x + ' ' + foo

Есть ли какая-то реальная разница между этими двумя? Или, в более общем смысле, __init__ что-то изменяет что-либо по сути относительно атрибутов класса? В в документации упоминается, что при создании экземпляра вызывается __init__. Означает ли это, что x в классе B устанавливается до создания экземпляра?

4b9b3361

Ответ 1

Да, проверьте это:

class A(object):
    def __init__(self):
        self.lst = []

class B(object):
    lst = []

и теперь попробуйте:

>>> x = B()
>>> y = B()
>>> x.lst.append(1)
>>> y.lst.append(2)
>>> x.lst
[1, 2]
>>> x.lst is y.lst
True

и это:

>>> x = A()
>>> y = A()
>>> x.lst.append(1)
>>> y.lst.append(2)
>>> x.lst
[1]
>>> x.lst is y.lst
False

Означает ли это, что x в классе B устанавливается до создания экземпляра?

Да, это атрибут класса (он разделяется между экземплярами). Хотя в классе А это атрибут экземпляра. Просто случается, что строки неизменяемы, поэтому нет никакой реальной разницы в вашем сценарии (кроме того, что класс B использует меньше памяти, поскольку он определяет только одну строку для всех экземпляров). Но в моем примере есть огромный.

Ответ 2

В первом примере у вас есть переменная экземпляра класса. Эта переменная доступна только через экземпляр (требуется самостоятельно).

class A():
    def __init__(self):
        self.x = 'hello'

print A.x -> AttributeError
print A().x -> 'hello'

Во втором примере у вас есть статическая переменная. Вы можете получить доступ к этой переменной благодаря имени класса A

class A():
  x = 'hello'

print A.x -> 'hello'
print A().x -> 'hello'

Фактически вы можете иметь статическую переменную и переменную экземпляра с тем же именем:

class A():
    x = 'hello'
    def __init__(self):
        self.x = 'world'

print A.x -> hello
print A().x -> world

Статическое значение разделяется между всеми экземплярами

class A():
    x = 'hello'

    @staticmethod
    def talk():
        print A.x

a = A()
print a.talk() -> hello

A.x = 'world'
print a.talk() -> world

У вас есть хорошая статья здесь: http://linuxwell.com/2011/07/21/static-variables-and-methods-in-python/

Ответ 3

Как утверждали другие, это разница между переменной в классе и переменной экземпляра класса. См. Следующий пример.

>>> class A:
...     a = []
... 
>>> class B:
...     def __init__(self):
...         self.b = []
... 
>>> a1 = A()
>>> a1.a.append('hello')
>>> a2 = A()
>>> a2.a
['hello']
>>> b1 = B()
>>> b1.b.append('goodbye')
>>> b2 = B()
>>> b2.b
[]

Для неизменяемых объектов, таких как кортежи, строки и т.д., сложнее заметить разницу, но для изменчивых он меняет все и все применяемые изменения распределяются между ВСЕМИ экземплярами этого класса.

Обратите также внимание на то, что такое же поведение происходит для аргументов по умолчанию для ключевого слова!

>>> class A:
...     def __init__(self, a=[]):
...         a.append('hello')
...         print(a)
... 
>>> A()
['hello']
>>> A()
['hello', 'hello']
>>> A()
['hello', 'hello', 'hello']

>>> class B:
...     def __init__(self, b=None):
...         if b is None:
...             b = []
...         b.append('goodbye')
...         print(b)
... 
>>> B()
['goodbye']
>>> B()
['goodbye']
>>> B()
['goodbye']

Такое поведение укусит много новых программистов на Python. Хорошо для вас, обнаружив эти различия на ранней стадии!

Ответ 4

вы используете init, вам не нужно использовать его в своем случае, вы можете просто

enter code here

 class some():
  def main(self):
      self.x=10
  def mathod_a(self,foo):
       print self.x+foo'

и если вы хотите использовать init, попробуйте

enter code here
class some ():
 def main(self):
     print(x)
 def init(self,x):
     self.x=x
     main()