Reputation: 2554
For example:
class Meta(type):
def __new__(cls, name, parents, attrs):
new_attrs={}
for k,v in attrs.items():
# Here attrs only has methods defined in "name", this is not I want.
print(k,v)
new_attrs[k] = v
return type.__new__(cls, name, parents, new_attrs)
class meta(metaclass=Meta):
pass
class a(object):
def a1(self):
return self.a2()
def a2(self):
print('a2 voked')
class b(a):
def b1(self):
return self.b2()
def b2(self):
return self.a1()
class c(b):
def c1(self):
return self.b1()
class d(c,meta):
def d1(self):
return self.c1()
x=d()
x.d1()
The result is:
>>>
__qualname__ meta
__module__ __main__
__qualname__ d
d1 <function d.d1 at 0x0000000002A7B950>
__module__ __main__
a2 voked
As you can see, in __new__
of Meta
, except special methods, only d1
is accessible. But I want to get all its parents' methods as well(.i.e a1 a2 b1 b2 and c1 objects) so I can do something useful when class d
is creating via metaclass, such as add a decorator to all its methods. so how ?
I know one similar way to get this, but it is a little complicated and in fact, it is after class d
is created.:
import inspect
class Print(object):
@classmethod
def printize(cls,):
for name,attr in inspect.getmembers(cls):
# here all methods are accessible
# you can do something like:
# setattr(cls,name, f(attr))
class d(c,Print):
def d1(self):
return self.c1()
d.printize()
Upvotes: 2
Views: 100
Reputation: 91149
The way you use it, all methods in the parent classes will already be present.
But you could walk through the parent classes provided by parents
and use their __dict__
(which you should do recursively, then) or use dir()
(which takes care of recursing into parent classes as well).
Another approach could be to apply meta
earlier.
Upvotes: 0
Reputation: 98118
x=d()
p = type(x)
while p != object:
print(p.__bases__)
p = p.__bases__[0]
Gives:
(<class '__main__.c'>, <class '__main__.meta'>)
(<class '__main__.b'>,)
(<class '__main__.a'>,)
(<class 'object'>,)
Or you can do:
import inspect
print(inspect.getmro(type(x)))
To get:
(<class '__main__.d'>, <class '__main__.c'>, <class '__main__.b'>,
<class '__main__.a'>, <class '__main__.meta'>, <class 'object'>)
Upvotes: 1