2

I'm trying to override the dir method in a Python class. Inside I want to call the builtin dir method, but my attempts at calling it seem to be calling my method, rather than the default implementation.

The correct way to override the __dir__ method in python This question seemed relevant but doesn't answer the question since it seems their issue was with extending a numpy class, not with calling the default dir implementation for the class

Relevant code

def __dir__(self):
    return builtins.dir(self) + self.fields()

In other words I want everything that would normally be listed plus some other things, but the builtins.dir() call just calls this function recursively.

I'm testing this in Python 3.6

Jimbo
  • 2,886
  • 2
  • 29
  • 45

1 Answers1

3

Since overriding __dir__ only matters in class' instances, you can do this:

class Test:
    def test(self):
        print('hey')

    def __dir__(self):
        return dir(Test) + ['hello']

Notice that dir(Test) is different from dir(Test()) because only the latter calls Test.__dir__.

Using dir(super()) inside Test.__dir__ also kinda works, but it only provides you with data for the parent class, so that dir(Test()) won't contain the names of the attributes present exclusively in the class Test.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • This works ok although I modified it to be dir(type(self)) since I'm working with a subclass of the class. Also, I think it would be good to add the dictionary as well, since now you are skipping the instance attributes. So you have `dir(type(self)) + list(self.__dict__.keys()) + self.fields()` The linked SO question in my question also references super, which as you mention I found not to work as expected. – Jimbo May 06 '18 at 13:24
  • I should also mention that although this works fine for me as a workaround it doesn't answer the question of how one might call a builtin function directly. I'm surprised that builtins.dir() calls my method. – Jimbo May 06 '18 at 13:29
  • @Jimbo, you _are_ calling the builtin function `dir` directly with `builtins.dir`. Overriding the `dir` function itself and overriding a `__dir__` method are very different. – ForceBru May 06 '18 at 13:32
  • I am confused. Calling `builtins.dir` from my `__dir__` method results in recursion (and hitting a recursion limit). It is not clear to me how you would, from within the user defined `__dir__` method, call a function that returns the same thing as if the `__dir__` method did not exist. – Jimbo May 06 '18 at 16:27