Skip to content Skip to sidebar Skip to footer

Does Python Has Methods Similar To __setattr__ But For Python Class?

Currently __setattr__ only works for instance. Is there any similar method for class? I am asking this question because I want to collect the list of defined attribute in order whe

Solution 1:

Yes, but that's not how you want to do it.

class MC(type):
  def __init__(cls, name, bases, dct):
    print dct
    super(MC, cls).__init__(name, bases, dct)

class C(object):
  __metaclass__ = MC
  foo = 42

Solution 2:

If you define __setattr__() on the metaclass of a class, it will be called when setting attributes on the class, but only after creating the class:

>>> class Meta(type):
...     def __setattr__(cls, name, value):
...         print "%s=%r" % (name, value)
... 
>>> class A(object):
...     __metaclass__ = Meta
... 
>>> A.a = 1
a=1

But it won't work at the time of class definition, so it's probably not what you want.

Getting the class attributes in the metaclass __init__() works, but you loose the order of definition (and multiple definitions as well).


Solution 3:

What I would do to solve your problem - but not your question - is to set the timestamp of the field creation create a counter of Field objects and set the current value of the counter to the created one:

class Field(object):
    count = 0
    def __init__(self, value, default=None, desc=None):
        self.value = value
        self.default = default
        self.desc = desc
        # Here comes the magic
        self.nth = Field.count
        Field.count += 1
        # self.created_at = time.time()

Then I would create a method for returning all fields ordered by its counter value:

class CfgObj(object):
    def params(self):
        ns = dir(self)
        fs = [getattr(self, field) 
                    for field in ns 
                    if isinstance(getattr(self, field), Field)]
        # fs = sorted(fs, key=lambda f: f.created_at)
        fs = sorted(fs, key=lambda f: f.nth)
        return fs

Its usage is intuitive:

class ACfg(CfgObj):
    setting1 = Field(str, default='set1', desc='setting1 ...')
    setting2 = Field(int, default=5, desc='setting2...')

print ACfg().params()

Clearly the fields are ordered by time of object creation, not field creation, but it can be enough for you. Is it?


Post a Comment for "Does Python Has Methods Similar To __setattr__ But For Python Class?"