Modification des attributs de classe par référence

Je suis relativement nouveau à Python et ont des problèmes avec immuables variables.

Je suis en train de modifier la valeur d'un attribut de classe (voiture, par exemple.de la couleur). La difficulté est que je ne peux pas utiliser l'espace de noms de la voiture pour le faire.

Jusqu'à maintenant, je n'ai pas trouvé un satisvying de réponse à mes questions. Dans le code ci-dessous j'ai essayé de résumer les solutions possibles (workarrounds) j'ai trouvé et leurs inconvénients:

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

En fait la fonction setattr() est à l'intérieur exactement de faire ce que je veux. Mais il fonctionne avec un argument de type chaîne.
J'ai essayé de regarder dans cette fonction, mais il semble être écrit en C++.

Donc dois-je utiliser C++ pour résoudre ce problème sans une workarround?
Ou est-il un Pythionic façon de faire cela?

  • Vous envoyer la voiture de l'objet lui-même de la fonction et de modifier l'attribut y acheter à l'aide de l'objet voiture dict, ou de définir une méthode à l'intérieur de la classe qui prend soin de changer l'attribut.
  • Serait-il possible pour vous de faire def change_attribute(obj, attribute, value): obj.__dict__[attribute] = value? Qui allait changer l'immuable objet directement sur la source. Et vous n'avez qu'à l'appeler par l'intermédiaire change_attribute(car1, 'color', 'blue')
  • Aussi qu'est-ce que l'application de votre choix?
  • Je voudrais l'utiliser dans un treeview modèle. Je ré-implémenté la fonction data() pour accéder à toutes les voitures attributs. L'arborescence doit toujours montrer exactement les données de la voiture. Par conséquent, je tiens à sauver la référence à la voiture.la couleur comme treeview.set_data(voiture.couleur, Qt.D'affichage). Lorsque treeview obtient des données() pour le dessin, il est toujours afficher les données dans la voiture.couleur. Mais en effet, il indique toujours "vert", la valeur initiale.
  • Pavan: c'est possible, mais alors je dois écrire une fonction pour chaque attribut. Cette coutures comme une solution de contournement pour moi. @Torxed: possible, mais j'ai l'inconvénient de l'utilisation d'une chaîne de l'attribut.
  • Que voulez-vous dire, vous ne pouvez pas utiliser l'espace de noms? Qu'est-ce que la prévention de votre écriture car1.color = "red" ou setattr(car1, "color", "red")?

InformationsquelleAutor Jan | 2017-05-18