Change inline function

Consider any custom pythonic class. If I call dir(obect_of_class) , I get a list of its attributes:

 ['__class__', '__delattr__', '__dict__', '__dir__', ... '__weakref__', 'bases', 'build_full_name', 'candidates', ... 'update_name']. 

In this list you can see 2 types of attributes:

  • built-in attributes
  • user defined.

I need to override __dir__ so that it returns only user-defined attributes. How can i do this?

Clearly, if I call myself in an overridden function, it gives me infinite recursion. So, I want to do something like this:

 def __dir__(self): return list(filter(lambda x: not re.match('__\S*__', x), dir(self))) 

but avoid endless recursion.

In general, how can I change a built-in function if I do not want to write it from scratch, but want to change an existing function?

+5
source share
2 answers

Use super to invoke the parent implementation of __dir__ ; avoid 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'] 
+8
source

Do you want to do this in your custom class or globally for the dir() function?

The first approach (only for the class):

 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 is done here calls __dir__() superclass (not the class itself) and filters it in the subclass.

Second approach (shadow 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 requests to dir() will be filtered out. As you can see, it will work for all types, including built-in types.

+2
source

Source: https://habr.com/ru/post/1239910/


All Articles