Jan*_*Jan 8 python attributes mutable
我对Python相对较新,并且对不可变变量有疑问。
我正在尝试更改类属性的值(例如car.color)。困难在于,我无法使用car的命名空间来执行此操作。
到目前为止,我还没有找到令人满意的答案。在下面的代码中,我试图总结发现的可能解决方案(工作环境)及其缺点:
class Car:
def __init__(self):
self.color = "green"
self.color_list = ["green"]
self.color_attrib = "green"
self.name = "VW Golf"
"""
and many more attributes...
"""
def makesetter(self, attribute):
def set_value(value):
attribute=value
return set_value
def set_color(self, value):
"in this function I directly have access to car.color and can change its value: "
self.color = value
def set_attrib(self, attribute_string, value):
setattr(self,attribute_string,value)
def change_attribute(attribute, value):
"In this function I can not access car.color directly"
attribute=value
def change_attribute_list(attribute, value):
"In this function I can not access car.color directly"
attribute[0] = value
if __name__ == "__main__":
car1 = Car()
change_attribute(car1.color, "red")
print(car1.color) # Color does not change because car1.color is immutable
g = car1.makesetter(car1.color)
g("red")
print(car1.color) # Color does not change because car1.color is immutable
change_attribute_list(car1.color_list, "red")
print(car1.color_list) # Color changes but seems like a workarround
# Disadvantage: in the namespace of car1, the user has to use a list to access a string value "car1.color_list[0]"
car1.set_color("red")
print(car1.color) # Color changes but seems like a workarround
# Disadvantage: Car needs a setter function for each attribute
car1.set_attrib("color_attrib","red")
print(car1.color_attrib) # Color changes but seems like a workarround
# Disadvantage: Attribute has to be passed as string & no auto completion while coding
Run Code Online (Sandbox Code Playgroud)
实际上,函数setattr()在内部完全可以实现我想要的功能。但是它可以使用字符串参数。我试图研究此功能,但它似乎是用C ++编写的。
那么,我是否必须使用C ++来解决此问题而无需进行工作?还是有一种Pythionic的方式来做到这一点?
问题是您正在尝试从类外部重新定义实例的值。由于在__init__中使用定义变量self,因此变量仅可用于该实例。这就是课程的重点-这就是使它们具有可扩展性和可重用性的原因。
理想情况下,您将在类内创建一个用于更新这些属性的方法,但是,如果您确实需要从外部函数更新该类,则必须将其定义为类级变量。例如:
class Car:
def __init__(self):
Car.color = "green"
Run Code Online (Sandbox Code Playgroud)
现在可以使用以下命令进行更新:
def change_attribute(attribute, value):
"In this function I can not access car.color directly"
Car.color=value
Run Code Online (Sandbox Code Playgroud)
在类之外,因为您尚未将其分配给一个特定实例。但是,这样做会带来问题。由于我们没有单独的实例变量,因此,如果我们尝试重新实例化该类,那么我们将停留在先前更改的内容上,即如果name ==“ main ”:
car1 = Car()
car2 = Car()
change_attribute(car1.color, "red")
print(car1.color) # Prints red
print(car2.color) # Prints red
change_attribute(car2.color, "blue")
print(car1.color) # Prints blue
print(car2.color) # Prints blue
Run Code Online (Sandbox Code Playgroud)
这就是为什么类本身应该是自包含的,并且是不可变的-实例本身应该更改。
| 归档时间: |
|
| 查看次数: |
14260 次 |
| 最近记录: |