Объявляющие участники только в конструкторе

Я происхожу из среды C++ к Python

Я объявлял членские переменные и устанавливал их в C++ esqe путь как так:

class MyClass:
    my_member = []

    def __init__(self,arg_my_member):
        self.my_member = arg_my_member

Затем я заметил в некотором открытом исходном коде, что начальное объявление my_member = [] был полностью не учтен и только создан в конструкторе.

Который, очевидно, возможен, поскольку Python является динамичным.

Мой вопрос, действительно ли это - предпочтительное или Pythonic способ сделать вещи, и там и за и против также?

7
задан zenna 24 July 2010 в 15:42
поделиться

4 ответа

То, как вы это делаете, означает, что теперь у вас есть «статический» член и «нестатический» член с тем же именем.

class MyClass:
    my_member = []

    def __init__(self, arg_my_member):
        self.my_member = arg_my_member


>>> a = MyClass(42)
>>> print a.my_member
42
>>> print MyClass.my_member
[]
9
ответ дан 6 December 2019 в 15:17
поделиться

Если вы определяете его внутри класса, то это переменная класса, а если вы определяете его внутри конструктора, то это объектная переменная. Таким образом, если вы не определяете ее внутри конструктора, то ВСЕ экземпляры класса имеют одну и ту же переменную класса.

4
ответ дан 6 December 2019 в 15:17
поделиться

Оба способа приемлемы для python, за исключением случая с изменяемыми значениями. Если вы объявите его, как в вашем примере, вы можете получить очень неожиданный результат:

>>> class MyClass:
...     my_member = []
... 
>>> A = MyClass()
>>> B = MyClass()
>>> A.my_member.append(1)
>>> A.my_member
[1]
>>> B.my_member.append(2)
>>> B.my_member
[1, 2]
>>> A.my_member
[1, 2]
>>> MyClass.my_member
[1, 2]

Поскольку члены класса генерируются только один раз, когда сам класс обрабатывается при загрузке модуля. Если ваш член предназначен для использования в области экземпляра, вы должны установить его в __init__

С неизменяемыми значениями все в порядке.

1
ответ дан 6 December 2019 в 15:17
поделиться

Это создает атрибут класса под названием my_member

class MyClass:
    my_member = []

Если бы у экземпляров не было переменной экземпляра под названием my_member, все экземпляры имели бы доступ к одному и тому же списку через self.my_member.

Поскольку вы создаете переменную экземпляра под названием my_member, вполне вероятно, что переменная класса никогда не используется и является лишь признаком путаницы

.
0
ответ дан 6 December 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: