如果python的类变量和实例变量名字一样会如何?

python中类变量是属于类的,不属于具体的对象,所有对象共享一个类变量。类变量可以通过类名.变量名访问,也可以通过实例化后的对象.变量名访问。那么,如果我给对象的变量起的名字和类变量同名会如何?我们写代码测试一下:

class Foo:
    name = "hello" # <- 类变量

    def set_instance_name(self, name):
        self.name = name # <- 实例变量
    
    def get_instance_name(self):
        return self.name
    
    def get_class_name(self):
        return Foo.name

foo = Foo()
print(f"{Foo.name=}")
print(f"{foo.get_instance_name()=}")
print(f"{foo.get_class_name()=}")

foo.set_instance_name("world")
print(f"{Foo.name=}")
print(f"{foo.get_instance_name()=}")
print(f"{foo.get_class_name()=}")

输出:

Foo.name='hello'
foo.get_instance_name()='hello'
foo.get_class_name()='hello'
Foo.name='hello'
foo.get_instance_name()='world'
foo.get_class_name()='hello'

可以看到,当读取self.name时,如果已经有实例变量则访问实例变量,否则访问类变量。当写入self.name时,会创建新的实例变量,不会改变类变量。

因此,类变量可以作为“实例化”对象的默认值使用。比如这段神奇的代码:

class Foo:
    name = "hello"

    def __init__(self) -> None:
        self.name = self.name

foo = Foo()
print(f"{foo.name=}")

foo.name = "world"

print(f"{foo.name=}")
print(f"{Foo.name=}")

__init__函数中出现了self.name=self.name,是不是很神奇?这里等于号右边因为还没有名字叫name的实例变量,因此访问到了类变量,等于号左边是实例变量。在创建后,因为实例变量有了name,之后再访问self.name就访问到了实例变量。

posted @ 2024-10-21 14:45  王冰冰  阅读(9)  评论(0编辑  收藏  举报