Атрибуты глобального класса Python - PullRequest
0 голосов
/ 11 декабря 2018

Я хочу создать базовый класс с атрибутом, который не должен изменяться.Любой производный класс из этого базового класса также должен иметь этот атрибут.Моя идея была:

class baseclass(object):
    flag = "some attr for all classes"
    def __init__(self, baseattr):
        self.baseattr = baseattr


class child(baseclass):
    def __init__(self, baseattr, childattr):
        super(child, self).__init__(baseattr)
        self.childattr = childattr

Я думал, если я знаю, посмотрите на ребенка .__ dict __:

print(child.__dict__["flag"])

, он должен вернуть «специальный атрибут ... базовый класс», но вместо этого я получаюKeyError:

Traceback (most recent call last):
  File "./test.py", line 14, in <module>
    print(child.__dict__["flag"])
KeyError: 'flag'

, тогда как при вызове baseclass .__ dict __ ['flag'] все в порядке.Есть ли способ установить флаги для всех производных классов, которые наследуются от базового класса?

1 Ответ

0 голосов
/ 11 декабря 2018

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

В целом, __dict__, к которому вы пытаетесь получить доступ, реализует пространство имен объекта.Предполагалось, что к нему не будет прямого доступа, как вы пытаетесь.Но для понимания я воспользуюсь им, чтобы проиллюстрировать разницу class instance против class object.

Вызов __dict__, каким вы были, даст вам дикт, содержащий атрибуты вашего child классаобъект (по умолчанию и те, которые вы определили в своем определении класса):

>>> child. dict

dict_proxy ({'module ':' main ',' doc ': None,' init ':})

ОднакоКогда вы решили добавить flag в ваш baseclass, как вы это сделали, вы определили его как часть вашего baseclass объекта класса.Например, он не объявляется каждый раз, а после того, как вы импортировали определение класса.Следовательно, вы можете видеть flag, если вы делаете:

>>> baseclass. dict

dict_proxy ({' module ':' main ',' flag ':' некоторый атрибут для всех классов ',' dict ':,' weakref ':,' doc ': Нет,' init ':})

Наконец, если вы получите доступ к экземпляру объекта __dict__, вы увидите атрибуты, которые вы объявили с помощью self (включая baseattr, который был объявлен при вызове super):

>>> child ('some base attr', 'some child attr'). dict

{'childattr': 'some child attr', 'baseattr': 'some base attr'}

При этом вам уже нужно получить доступ к flag из любого экземпляра объекта.Точнее говоря, у вас есть доступ ко всем атрибутам, определенным в определении класса, определении класса наследования и в вашем экземпляре.Поэтому я действительно рекомендую вам прекратить использование __dict__ и получить доступ к вещам, для которых они были предназначены:

>>> your_obj_instance = child ('some base attr', 'some child attr')

>>> your_obj_instance.childattr

'некоторые дочерние атрибуты'

>>> your_obj_instance.baseattr

'некоторые базовые атрибуты'

>>> your_obj_instance.flag

'некоторые атрибуты для всех классов'

...