Reputation: 10504
python version 3.5.2
I tried to get parent class from a child class:
class A:
pass
class B(A):
pass
after a little research, I got a solution from python doc: use __base__
. (a special class attribute)
But I couldn't find this "__base__"
in B.__dict__
or dir(B)
, which are my normal ways of getting attributes.
This is definitely class related information, if it's not in B.__dict__
where is it? (although I realized that "__base__"
is returned by type(B).__dict__
)
And why isn't dir()
returning it? based on this stackoverflow question I read, dir()
has some logics behind and it is supposed to return "a complete picture of all available attributes."
I initally thought this is hiding on purpose...but you can still easily manipulate a child's parent:
class C:
pass
B.__bases__ = (C,) # voila, B got a new Dad
Upvotes: 1
Views: 86
Reputation: 387677
See the note on dir()
(emphasis mine):
Note: Because
dir()
is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.
B
is a class, its metaclass is type
. So if you really want the full picture, you should also look as the metaclass’ dir()
:
>>> B.__class__ is type
True
>>> dir(type)
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__',
'__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__instancecheck__', '__itemsize__', '__le__', '__lt__',
'__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', '__qualname__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__',
'__weakrefoffset__', 'mro']
And there you have __base__
and __bases__
, and also those other things that appeared in the list you linked, like mro
and __subclasses__
.
Upvotes: 1