Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python class properties

I'm trying to find the best way to extend a class variable. Hopefully an example of the method I've come up with so far will make this clear.

class A(object):
    foo = ['thing', 'another thing']

class B(A):
    foo = A.foo + ['stuff', 'more stuff']

So I'm trying to make the subclass inherit and extend the parent's class variable. The method above works, but seems a bit kludgey. I'm open to any suggestion, including accomplishing something similar using a completely different approach.

Obviously I can continue to use this method if need be, but if there's a better way I'd like to find it.

like image 843
gbutler Avatar asked Jul 26 '12 18:07

gbutler


People also ask

What are class properties in Python?

Class Properties The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.

What are class properties?

The collection of properties assigned to a class defines the class. A class can have multiple properties. For example, objects classified as computers have the following properties: Hardware ID, Manufacturer, Model, and Serial Number.

How do you access the attributes of a class in Python?

Attributes of a class can also be accessed using the following built-in methods and functions : getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute.

How do I change class attributes in Python?

But be careful, if you want to change a class attribute, you have to do it with the notation ClassName. AttributeName. Otherwise, you will create a new instance variable.


2 Answers

Could use a metaclass:

class AutoExtendingFoo(type):

    def __new__(cls, name, bases, attrs):
        foo = []
        for base in bases:
           try:
               foo.extend(getattr(base, 'foo'))
           except AttributeError:
               pass
        try:
            foo.extend(attrs.pop('foo_additions'))
        except KeyError:
            pass
        attrs['foo'] = foo
        return type.__new__(cls, name, bases, attrs)

class A(object):
    __metaclass__ = AutoExtendingFoo
    foo_additions = ['thing1', 'thing2']
    # will have A.foo = ['thing1', 'thing2']

class B(A):
    foo_additions = ['thing3', 'thing4']
    # will have B.foo = ['thing1', 'thing2', 'thing3', 'thing4']

class C(A):
    pass
    # will have C.foo = ['thing1', 'thing2']

class D(B):
    pass
    # will have D.foo = ['thing1', 'thing2', 'thing3', 'thing4']
like image 82
Silas Ray Avatar answered Oct 13 '22 16:10

Silas Ray


I definitively would go for instance-properties. (if I got it right, they are not bound to be static for your case?!)

>>> class A:
...     @property
...     def foo(self):
...         return ['thin', 'another thing']
...
>>> class B(A):
...     @property
...     def foo(self):
...         return super().foo + ['stuff', 'thing 3']
...
>>> B().foo
['thin', 'another thing', 'stuff', 'thing 3']
like image 27
gecco Avatar answered Oct 13 '22 15:10

gecco