6

I want to create a object with certain properties. I want to add them dynamically. Similar to Adding a Method to an Existing Object Instance, but then with properties instead of methods. A simple example follows.

I like to create dynamically:

class A():
    @property
    def a(self):
        return self._a
    @a.setter
    def a(self, x):
        self._a = 10*x

    @property
    def b(self):
        return self._b
    @b.setter
    def b(self, x):
        self._b = 10*x

To do this with methods, i would do:

class B():
    def __init__(self):
        for i in range(70,80):
            self.__dict__[chr(i)] = types.MethodType(lambda self,x: x*i, self)

For properties I tried:

class B():
    def __init__(self):
        for i in range(70,80):
            def tmp(self, x):
                self._x = i*x
            self.__dict__[chr(i)] = property(fget=lambda self: self._i, fset=tmp)

I also found the types.DynamicClassAttribute, but I am not sure if this will help.

A relevant question is asked here, about adding properties to a class (in python 2): Dynamically adding @property in python . I do not see how I can extend this to instances of a class.

Background

I want to write a "driver" for the lantz project to use a camera via the PyPylon wrapper. The camera has some properties, which are not known in advance. I want to add all properties as Feats (some decorator supplied by lantz, which looks similar to a property: it has a getter and a setter).

Edit: it look likes How to add property to a class dynamically? is the same question

2

1 Answer 1

4

This comment gave a hint to the answer.

The follow function (inspired on 1) adds a property to a single instance of a class. It does it by creating a new class on the fly.

def attach_dyn_propr(instance, prop_name, propr):
    """Attach property proper to instance with name prop_name.

    Reference: 
      * https://stackoverflow.com/a/1355444/509706
      * https://stackoverflow.com/questions/48448074
    """
    class_name = instance.__class__.__name__ + 'Child'
    child_class = type(class_name, (instance.__class__,), {prop_name: propr})

    instance.__class__ = child_class

Example and test:

def getter(self): print('Get!')
def setter(self, value): print('Set to {!r}!'.format(value))
def deleter(self): print('Delete!')
prop = property(getter, fset=setter, fdel=deleter)

class Foo: pass
foo = Foo()
foo2 = Foo()
attach_dyn_propr(foo, 'p', prop)

foo.p
foo2.p

... Get
... AttributeError: 'Foo' object has no attribute 'p'
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.