2016-11-01 3 views
-2

У меня проблема с объявлением переменной в дочернем классе. Я упростил это дело, потому что код слишком длинный и имеет много зависимостей. Так вот дело:Как изменить значение глобальной переменной в дочернем классе python?

У меня есть 2 классов A и B:

class A(): 
    global_var=0 
    def some_function(self): 
      return self.global_var+2 

class B(A): 

     def method_that_returns_global_var(self): 
      #do some operations on global_var 
      global_var=(.....some logic....) 
      return global_var 

Как провозглашают global_var в дочернем классе B так, что он выполняет функцию родительского класса some_function со значением global_var дочернего класса B

+1

PS: пожалуйста, когда вниз голосование, объясните нам, как новички, почему: '( или, по крайней мере, говорят, что это невозможно или питон не позволяет это !! –

ответ

3

Итак ... Есть пара понятий, которые вы, вероятно, должны уточнить.

То, что 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__ ... и тому подобных. :-)

+0

спасибо большого за эти руководящие принципы :))) –

+1

Добро пожаловать. Я знаю, что может получиться немного сложнее **: -) ** (и дождитесь, пока вы начнете изучать, что 'class' также является экземпляром типа' type', haha) ... Weeeell ... это может быть для другой случай, **; -) **. Получайте удовольствие от кодирования! – BorrajaX

1

Несмотря на «глобальное» имя, переменная на самом деле является полем класса. Вы можете переписать его в дочернем классе, как это (я укоротить его «вар»):

class A(): 
    var = 0 
    def some_function(self): 
      return self.var + 2 

class B(A): 
    var = 1 


B().some_function() # =3 
1

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

 
class A(): 
    var = 123 

print(A.var) 
>>> 123 

Эта переменная будет получить по наследству, так что вы должны быть в состоянии сделать это

 
class B(A): 
    pass 

print(B.var) 
>>> 123 

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

 
class C(A): 
    var = 234 

    def inc_var(self): 
     self.var += 1 

print(C.var) 
>>> 234 
c = C() 
c.inc_var() 
print(C.var) 
>>> 235 
Смежные вопросы