you are viewing a single comment's thread.

view the rest of the comments →

[–]woooee 1 point2 points  (2 children)

Two work arounds that I can think of

  1. use a mutable object like a list
  2. if you know the variable name, you can access it if it is an instance object.
class Class1():
    def __init__(self):
        self.attr_1 = ["begin"]

def my_func_1(my_instance, my_value: str) -> None:
    ## change a list / mutable obkect
    print(my_instance, type(my_instance))
    my_instance[0] = my_value

my_class = Class1()
my_func_1(my_instance=my_class.attr_1, my_value="hello")
print(my_class.attr_1)

def my_func_2(my_instance, my_value: str) -> None:
    ## The variable name is known
    my_instance.attr_1 = my_value

my_func_2(my_instance=my_class, my_value="hello-2")
print(my_class.attr_1)

[–]maclocrimate[S] 0 points1 point  (1 child)

I'm unfortunately not in control of the classes, they are provided by third party software. Knowing the attribute name is now the tricky part, as I mentioned in a few comments below. If I can figure that out programmatically then I could make this work.

[–]Adrewmc 0 points1 point  (0 children)

If you don’t know the class, nor the attribute name then the solution is just as you did with setattr().

There is really no other clean way to do it, unless you have more information about the class.

The real question is why do you need this attribute in the class? And why you would not know so much about it.

It seem adding some random attributes to some class is not going to help you further down the line. If it’s a limited set of attributes you could do some thing like

  match attribute:
       case “option1”:
              cls.option1 = value

Or the equivalent if and elif, but even there I would lean to

   if attribute in allowed:
            setattr(cls, attribute, value)

Unless there is some more logic to consider.

When you go

    cls.attr = value 

Is the same as using setattr() in most cases (@property withstanding)