#python #class #object #inheritance #constructor
Вопрос:
Приведенный ниже исходный код вызовет исключение в последней строке. Почему возникает исключение, если это два разных объекта?
class BaseClass(object):
accounts = dict()
def AddAccount(self, account_id, account_var):
if account_id in self.accounts.keys():
raise Exception('Account already exists')
self.accounts.update({account_id: account_var})
class Class1(BaseClass):
pass
class Class2(BaseClass):
pass
ACCOUNT_ID = '123'
c1 = Class1()
c2 = Class2()
c1.AddAccount(ACCOUNT_ID, 'abc')
c2.AddAccount(ACCOUNT_ID, 'abc')
Я пытался вызвать конструктор внутри каждого класса, но это не решает проблему. Мне это нравилось в каждом классе:
def __init__(self):
super().__init__()
Похоже BaseClass
, что это всегда статический объект. Когда я изменюсь в одном объекте, он изменится в другом.
Комментарии:
1. «всегда статичный объект. Когда я изменюсь в одном объекте, он изменится в другом». да, в этом смысл атрибутов класса
2. В отличие от других языков, классы Python определяют только атрибуты классов, но никогда атрибуты экземпляров. Атрибуты экземпляра всегда создаются путем прямой модификации экземпляров, хотя обычно это делается с помощью методов экземпляра.
Ответ №1:
Вы определили accounts
как переменную класса, а не переменную экземпляра. Вместо этого вы должны определить accounts
в __init__
методе своего базового класса, чтобы он создавался с другой ссылкой для каждого экземпляра создаваемого вами класса.
class BaseClass(object):
def __init__(self):
self.accounts = dict()
def AddAccount(self, account_id, account_var):
if account_id in self.accounts.keys():
raise Exception('Account already exists')
self.accounts.update({account_id: account_var})
Ответ №2:
Вы определили переменную класса в теле своего BaseClass
.
Даже если вы ссылаетесь на него, self.accounts
это не переменная экземпляра.
Например, если вам нужна переменная экземпляра, вам следует инициализировать ее с __init__()
помощью self.accounts = {}