python中类方法和静态变量的行为
behavior of classmethods and static variables in pythone
假设我有以下 classes
class Parent:
message = "Hello World"
@classmethod
def print_message(cls):
print(cls.message)
@classmethod
def change_message(cls, new_message):
cls.message = new_message
class Child_one(Parent):
@classmethod
def print_messsage(cls):
print (cls.message)
@classmethod
def change_message(cls, new_message):
cls.message = new_message
class Child_two(Parent):
@classmethod
def print_message(cls):
print(cls.message)
我想我的问题是 child class 的 cls
指的是什么,因为如果我更改 [=42] 中的静态变量 message
=] class 它正确地改变了 message
在两个 children
中的值
Parent.change_message("This is new message")
Child_one.print_message() # This is new message
Child_two.print_message() # This is new message
这是我预期的行为,cls.message
都引用了 parent class 的消息。但是这样做
Child_one.change_message("I am child one")
导致
等行为
Parent.print_message() # This is new message
Child_one.print_message() # I am child one
Child_two.print_message() # This is new message
所以Child_one的cls.message
变量不再指向parentclass的消息。
在其他语言中,例如 c++
或 c#
static 更改 parent class 或 child class 的静态变量导致所有 parent 和派生的 classes 发生变化。有没有办法在 python
中复制这种行为,如果没有,为什么不呢?
写入时:
只要您将某物分配给 class 或对象的成员,而该成员按名称不存在,它就会被创建。
事实上,一个成员的名字出现在基础 class 中并没有改变任何东西。它是在 class 本身中创建的。
阅读:
然后进行名称解析:首先尝试在 class 本身中找到一个成员,然后在其基础 classes.
中找到一个成员
Frank-Rene 的回答是绝对正确的,您可以通过观察 class 变量的内存地址看到这种行为:
print(Parent.message, Child_one.message) #identical memory addresses
Child_one.change_message("something")
print(Parent.message, Child_one.message) #now they are different
这是因为 Python 中的每个 class 都将其属性保存在 dunder 字典 (__dict__
) 中,如果它们未被覆盖,它们将引用父项直到被修改。
对于您的用例,您可能对 Python 的 borg 设计模式感兴趣:https://github.com/faif/python-patterns/blob/master/patterns/creational/borg.py
假设我有以下 classes
class Parent:
message = "Hello World"
@classmethod
def print_message(cls):
print(cls.message)
@classmethod
def change_message(cls, new_message):
cls.message = new_message
class Child_one(Parent):
@classmethod
def print_messsage(cls):
print (cls.message)
@classmethod
def change_message(cls, new_message):
cls.message = new_message
class Child_two(Parent):
@classmethod
def print_message(cls):
print(cls.message)
我想我的问题是 child class 的 cls
指的是什么,因为如果我更改 [=42] 中的静态变量 message
=] class 它正确地改变了 message
在两个 children
Parent.change_message("This is new message")
Child_one.print_message() # This is new message
Child_two.print_message() # This is new message
这是我预期的行为,cls.message
都引用了 parent class 的消息。但是这样做
Child_one.change_message("I am child one")
导致
等行为Parent.print_message() # This is new message
Child_one.print_message() # I am child one
Child_two.print_message() # This is new message
所以Child_one的cls.message
变量不再指向parentclass的消息。
在其他语言中,例如 c++
或 c#
static 更改 parent class 或 child class 的静态变量导致所有 parent 和派生的 classes 发生变化。有没有办法在 python
中复制这种行为,如果没有,为什么不呢?
写入时:
只要您将某物分配给 class 或对象的成员,而该成员按名称不存在,它就会被创建。
事实上,一个成员的名字出现在基础 class 中并没有改变任何东西。它是在 class 本身中创建的。
阅读:
然后进行名称解析:首先尝试在 class 本身中找到一个成员,然后在其基础 classes.
中找到一个成员Frank-Rene 的回答是绝对正确的,您可以通过观察 class 变量的内存地址看到这种行为:
print(Parent.message, Child_one.message) #identical memory addresses
Child_one.change_message("something")
print(Parent.message, Child_one.message) #now they are different
这是因为 Python 中的每个 class 都将其属性保存在 dunder 字典 (__dict__
) 中,如果它们未被覆盖,它们将引用父项直到被修改。
对于您的用例,您可能对 Python 的 borg 设计模式感兴趣:https://github.com/faif/python-patterns/blob/master/patterns/creational/borg.py