在__init__函数内部和函数外部定义变量之间有什么区别

时间:2019-04-17 06:30:24

标签: python class oop global-variables

我想学习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 个答案:

答案 0 :(得分:1)

在类级别设置的属性由该类的每个实例共享。

__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.

答案 1 :(得分:0)

欢迎来到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)

答案 2 :(得分:0)

首先,我将您的课程简化如下。 这里的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