В чем разница между определением переменной внутри функции __init__ и вне функции - PullRequest
0 голосов
/ 17 апреля 2019

Я хочу изучить основы классов в Python и застрял.Я объявил одно и то же имя переменных класса и переменной экземпляра, чтобы лучше понять разницу, но когда я использую переменную класса внутри методов класса, она показывает ошибку, такую ​​как NameError: глобальное имя «a» не определено.Может кто-нибудь сказать, пожалуйста, как объявить переменную класса внутри и снаружи класса, если переменные класса и переменные экземпляра имеют одинаковые именаКод указан ниже, и поэтому ошибка в выводе

class abc:
    a=10
    def __init__(self,a):
        self.a=a
    def mod1(self):
        global a
        a=5
        self.a=105
    def mod2(self):
        a=15
        self.a=110
    def read(self):
        print(self.a)
        print(a)

b=abc(20)
print(b.a)
b.read()
b.mod1()
b.read()
b.mod2()
b.read()

Ошибка

20
20
Traceback (most recent call last):
  File "/Users/rituagrawal/PycharmProjects/untitled2/code/garbage.py", line 18, in <module>
    b.read()
  File "/Users/rituagrawal/PycharmProjects/untitled2/code/garbage.py", line 14, in read
    print(a)
NameError: global name 'a' is not defined

Process finished with exit code 1

Ответы [ 3 ]

1 голос
/ 17 апреля 2019

Атрибуты, установленные на уровне класса, являются общими для каждого экземпляра класса.

Атрибуты, установленные для экземпляра в __init__ или других методах, например, self.a = a, различны для каждого экземпляра и доступны в каждом методе.

Ссылки также могут быть установлены в методе - a = 15 - и это только в рамках метода. print(a) в вашем методе read() завершается неудачно, потому что a не был установлен в этом методе.

Обновление

Код для иллюстрации.

class MyClass:
    a = 10

    def __init__(self, b):
        self.b = b

    def read(self):
        c = 99

        print(self.a) # Class attribute - the same for all instances of MyClass
        print(self.b) # Instance attribute - each instance of MyClass has it's own, available in all methods
        print(c) # Local - only available in this method.
0 голосов
/ 17 апреля 2019

Для начала я упростил ваш класс следующим образом.Здесь a, переменная класса, упоминается внутри функций класса с использованием abc.a.На a, которая является переменной экземпляра, ссылаются, используя self.a

class abc:

    a=5

    def __init__(self,a):
        self.a=a

    def set(self, class_a, instance_a):

        abc.a=class_a
        self.a=instance_a

    def read(self):

        print(abc.a)
        print(self.a)

Затем мы начинаем с определения класса и пытаемся прочитать обе переменные.Переменная класса по-прежнему равна 5, а переменная экземпляра равна 20

b=abc(20)
b.read()
#5
#20

Затем я устанавливаю переменную класса и экземпляра a и пытаюсь их прочитать.Переменная класса изменяется на 30, а переменная экземпляра изменяется на 60

b.set(30, 60)
b.read()
#30
#60

Мы также можем напрямую обращаться к обеим переменным вне класса, используя instance_object.a для переменной экземпляра и ClassName.a для переменной класса.

print(b.a)
#30
print(abc.a)
#60
0 голосов
/ 17 апреля 2019

Добро пожаловать в SO Ritu Agrawal.

self.a 

- переменная экземпляра, как вы, похоже, догадались.Если вы хотите сослаться на статическую (классовую) переменную a, вам следует использовать:

abc.a

Итак:

class abc:
    a=10
    def __init__(self,a):
        self.a=a
        abc.a = 40

b=abc(20)
print(b.a)
print(abc.a)

Вы также можете использовать член __class__ экземпляра,итак:

class abc:
    a=10
    def __init__(self,a):
        self.a=a
        __class__.a = 40

b=abc(20)
print(b.a)
print(b.__class__.a)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...