通过引用更改类属性 [英] Changing class attributes by reference

查看:80
本文介绍了通过引用更改类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Python来说还比较陌生,并且对不可变变量有疑问.

I'm relatively new to Python and have problems with immutable variables.

我正在尝试更改类属性的值(例如car.color).困难在于,我无法使用car的命名空间来完成此操作.

I'm trying to change the value of a class attribute (e.g. car.color). The difficulty is, that I can not use the namespace of car for doing this.

到目前为止,我还没有找到对我的问题的令人满意的答案.在下面的代码中,我试图总结我发现的可能解决方案(工作环境)及其缺点:

Up to now I did not find a satisvying answer to my questions. In the code below I tried to summarize the possible solutions (workarrounds) I found and their disadvantages:

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

实际上,函数setattr()在内部完全可以实现我想要的功能.但是它可以与字符串参数一起使用. 我试图研究此功能,但它似乎是用C ++编写的.

Actually the function setattr() is internally exactly doing what I want. But it works with a string argument. I tried to look into this function but it seems to be written in C++.

那么我是否必须使用C ++来解决此问题,而无需进行工作? 还是有一种Pythionic方式?

So do I have to use C++ to solve this problem without a workarround? Or is there a Pythionic way of doing this?

推荐答案

问题是您试图从类外部重新定义实例的值.由于在__init__中使用self定义变量,因此它们仅可用于该实例.这就是课程的重点-这就是使它们具有可扩展性和可重用性的原因.

The problem is you are trying to redefine the value of an instance from outside of the class. Since in __init__ you are defining your variables with self, they are only available for that instance. This is the point of a class - it's what makes them extensible and reusable.

理想情况下,您将在类中创建一个方法 来更新这些属性,但是,如果您确实需要从外部函数中更新该类,则必须将其定义为一个类级别变量.例如:

Ideally, you would make a method within the class that would update those attributes, however, if you really need to update the class from an external function, you will have to define it as a class level variable. For instance:

class Car:

    def __init__(self):
        Car.color = "green"

现在可以使用以下方式更新:

can now be updated using:

def change_attribute(attribute, value):
    "In this function I can not access car.color directly"
    Car.color=value

在类之外,因为您尚未将其分配给一个特定实例.但是,这样做会带来问题.由于我们没有单独的实例变量,因此,如果我们尝试重新实例化该类,那么我们将被先前更改的内容所束缚,即 如果名称 =="主要":

outside of the class because you have not assigned it to one specific instance. Doing this presents a problem, however. Since we don't have a separate instance variable, if we try to re-instantiate the class, we are stuck with what was previously changed, i.e. if 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

这就是为什么类本身应该是自包含的并且应该是不可变的-实例本身应该更改.

This is why classes themselves should be self contained and are meant to be immutable - the instance itself should be changed.

这篇关于通过引用更改类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆