Let's consider any user-defined pythonic class. If I call dir(obect_of_class)
, I get the list of its attributes:
['__class__', '__delattr__', '__dict__', '__dir__', ... '__weakref__', 'bases',
'build_full_name', 'candidates', ... 'update_name'].
You can see 2 types of attributes in this list:
I need to override __dir__
so, that it will return only user defined attribltes. How I can do that?
It is clear, that if in overridden function I call itself, it gives me infinite recursion. So, I want to do somethig like this:
def __dir__(self):
return list(filter(lambda x: not re.match('__\S*__', x), dir(self)))
but evade the infinite recursion.
In general, how can I modify a built-in function if I don't want to write it from scratch but want to modify the existing function?
Use super
to call parent's implementation of __dir__
; avoid the recursion:
import re
class AClass:
def __dir__(self):
return [x for x in super().__dir__() if not re.match(r'__\S+__$', x)]
def method(self):
pass
>>> dir(AClass())
['method']
Do you want to do it on your custom class or globally for dir()
function?
First approach (class-only):
class MyClass:
def f(self):
return None
def __dir__(self):
return list(filter(lambda x: not re.match('__\S*__', x), super().__dir__()))
print(dir(MyClass())) # ['f']
Basically what's done here is calling __dir__()
of superclass (not class itself) and filtering it in subclass.
Second approach (shadowing global dir function):
import re
def dir(obj):
return list(filter(lambda x: not re.match('__\S*__', x), __builtins__.dir(obj)))
print(dir({})) # ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
Here all calls to dir()
would be filtered. As you can see - it'll work for all types, including built-in types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With