Noa Cahan
Noa Cahan

Reputation: 23

Accessing attributes in class using metaclass - python

I am new to python metaclass and running the following code:

    class A(type):

        @classmethod
        def _handle_attrs(cls, class_name, bases, attrs, **kwargs):

            # Now lets find all handlers defined for this class
            current_attr = [(att, getattr(attrs[att], "__my_attr")) for att in attrs if
                          hasattr(attrs[att], '__my_attr')]

            print hasattr(attrs, '__my_attr') # returns False

        def __new__(cls, class_name, bases, attrs, **kwargs):
            cls._handle_attrs(class_name, bases, attrs, **kwargs)
            return type.__new__(cls, class_name, bases, attrs, **kwargs)


    # adding the decorators args as a class attribute

    def my_decorator(*args, **kwargs):
        def _my_decorator(cls):
            if hasattr(cls, '__my_attr'):
                cls.__my_attr.update(kwargs)
            else:
                cls.__my_attr = kwargs
            return cls
        return _my_decorator

    class B:
        __metaclass__ = A

        def get_attr_dict(self):
            return getattr(self, '__my_attr', None)


    @my_decorator(w = 'W')
    @my_decorator(z = 'Z')
    class C(B):
        x = 'X'
        y = 'Y'

    test = C()

    print test.__class__.__dict__ 
    print test.__my_attr # this returns {'w': 'W', 'z': 'Z'}

I am adding class attributes to C class by using the class decorator - my_decorator. In _handle_attrs function I would like to do something to the added attributes.

The problem is that the added attributes are added under : test._ _class__._ _dict__ and when creating C in metaclass, I don't know how to access them...

Upvotes: 2

Views: 1133

Answers (1)

user2390182
user2390182

Reputation: 73450

The metaclass' __new__ is run upon the definition of a class that uses it. Since

@my_decorator(w = 'W', z = 'Z')
class C(B):
    x = 'X'
    y = 'Y'

is equivalent to

class C(B):
    x = 'X'
    y = 'Y'

C = my_decorator(w = 'W', z = 'Z')(C)

it should be evident that the metaclass has already done its job by the time your decorator adds its attributes.

Upvotes: 2

Related Questions