Итак ... Есть пара понятий, которые вы, вероятно, должны уточнить.
То, что global_var
не является глобальным переменной. Это атрибут класса. Это означает, что он определен только один раз: когда вы объявляете класс. После этого все классы того же типа (или их унаследованные классы) будут делиться той же переменной. Я нашел this, что, вероятно, полезно.
Это означает, что всех экземпляров типа A
или любой типа наследования от A
(а именно B
в примере), которые вы создаете поделятся. Тем не менее, вы все равно должны получить доступ к ним через self
или через cls
(обычно экземпляр class
назван так в classmethods) Что вы делаете в этом методе ...
def method_that_returns_global_var(self):
#do some operations on global_var
global_var=(.....some logic....)
... просто создание global_var
локального переменная методы method_that_returns_global_var
(и не имеет ничего общего с global_var
в классе)
Если это поможет вам увидеть его (это, конечно, помогает мне), вы можете думать об этом global_var
, прилагаемых к class
, а не экземпляров этого класса.
Это означает, что класс B
уже имеет доступ к global_var
, так как он наследует от A
.Когда вы пытаетесь получить доступ к global_var
в методе экземпляра (те, которые вы передаете self
, в общем говоря), то, что интерпретатор попытается сделать, это найти атрибут global_var
среди экземпляров экземпляра (self
). Если он не найдет его, он пойдет в класс. Однако (очень важно), когда вы назначить в метод экземпляра (вы self.global_var = whatever
), переводчик будет просто поместить global_var
в например (в его «внутренний» словарь атрибутов __dict__
) Не позволяйте, смущающих вы!
Смотреть это:
class A(object):
global_var = 5
def some_function(self):
return self.global_var + 2
def print_global_bar(self):
print("Global bar value=%s" % self.global_var)
class B(A):
def method_that_returns_global_var(self):
# do some operations on global_var
self.global_var = 1000
return self.global_var
if __name__ == "__main__":
b = B()
b.print_global_bar()
b.method_that_returns_global_var()
b.print_global_bar()
print("Because `method_that_returns_global_var` does an ASSIGNMENT, now I have two `global_var`."
" One in the class, one in the instance `b`")
print("In the instance: %s" % b.global_var)
print("In the class: %s" % b.__class__.global_var)
Он выводит:
Global bar value=5
Global bar value=1000
Because `method_that_returns_global_var` does an ASSIGNMENT, now I have two `global_var`. One in the class, one in the instance `b`
In the instance: 1000
In the class: 5
Если вы хотите, чтобы выполнить задание переменной класса в method_that_returns_global_var
вы должны либо сделать это метод класса (с @classmethod
декоратора) или получить доступ к классу экземпляра (находится в self.__class__
)
Просмотреть сейчас:
class A(object):
global_var = 5
def some_function(self):
return self.global_var + 2
def print_global_bar(self):
print("Global bar value=%s" % self.global_var)
class B(A):
def method_that_returns_global_var(self):
# do some operations on global_var
self.__class__.global_var = 1000
return self.global_var
if __name__ == "__main__":
b = B()
b.print_global_bar()
b.method_that_returns_global_var()
b.print_global_bar()
print("In the instance: %s" % b.global_var)
print("In the class: %s" % b.__class__.global_var)
Выходы:
Global bar value=5
Global bar value=1000
In the instance: 1000
In the class: 1000
разницу? В первом методе self.global_var = 1000
создает новый атрибут в экземпляре , не считая того, что записано в class
. В принципе, у вас есть два s вокруг: один подключен к классу (значение которого по-прежнему 5
) и один подключен к экземпляру (значение которого равно 1000
). Во втором методе, вы получаете доступ и изменение всего времени переменного класса (A.global_var
)
Я рекомендую вам играть немного больше с этим ... Больше print
с, больше .__class__
... и тому подобных. :-)
PS: пожалуйста, когда вниз голосование, объясните нам, как новички, почему: '( или, по крайней мере, говорят, что это невозможно или питон не позволяет это !! –