0

I have a class:

class A:
    def foo(self):
        print("A.foo")

I want a method of the class to have an attribute so I can do something like A.foo.b.

I tried creating a decorator which returns a callable class:

class AttrStorage:
    def __init__(self, b, method):
        self.b = b
        self.method = method

    def __call__(self, *args, **kwargs):
        return self.method(*args, **kwargs)


def add_attr(b):
    def wrapper(method):
        return AttrStorage(b, method)

    return wrapper

So I could use it like this:

class A:
    @add_attr(1)
    def foo(self):
        print("A.foo")

Fortunately A.foo.b worked, but when I used the method, it gave an error:

>>> A.foo.b
1
>>> A().foo()
TypeError: foo() missing 1 required positional argument: 'self'

Is this possible in python? If so, how do I do it?

ArjunSahlot
  • 426
  • 5
  • 13
  • 2
    Does this answer your question? -- https://stackoverflow.com/a/20306101/13261176 – Teejay Bruno Aug 02 '21 at 01:18
  • 1
    I think Teejay found the answer to your question, but I'm so curious: why would you ever want to do this? It sounds like there's *got* to be a way to accomplish the end-goal without hacking python, but what do I know, maybe not :) – en_Knight Aug 02 '21 at 01:23
  • @TeejayBruno, Thanks! After searching for a while I wasn't able to find any answers, I don't know how I missed that one. Yes, it does solve my problem. – ArjunSahlot Aug 02 '21 at 01:24
  • You can directly add an attribute to a method (actually the function object) like `A.foo.b = something`. Alternatively your "AttrStorage" can implement the descriptor protocol to behave like a method. – Michael Butscher Aug 02 '21 at 01:24
  • @en_Knight, this is why I need this: I am creating a base class, so the methods of the class can get overridden. If someone would like to override a method then they can look at the `class.method.guideline` to guide them. – ArjunSahlot Aug 02 '21 at 01:26
  • 2
    @SaladHead isn't that what the docstring is for? How would they know to look for "guidline" in the first place, since it's different than the standard place (plus, docstring works with the "docs" command and standard documentation tools like sphinx). For extra help, you can make it an abstract class and mark the methods with the "abstractmethod" decorator, forcing people to implement the method themselves – en_Knight Aug 02 '21 at 01:29
  • If it's relevant: https://docs.python.org/3/library/abc.html . Not sure that it is, but often handy – en_Knight Aug 02 '21 at 01:31
  • @SaladHead you shouldn't be using class attributes for this. As others have noticed, the problem is that the callable object you defined does *not implement the descriptor protocol to bind the instance to the method* as a normal function object does. – juanpa.arrivillaga Aug 02 '21 at 02:39
  • Thanks for all the feedback. I decided to use a guideline attribute to make it more explicit, but docstrings could work well as well. – ArjunSahlot Aug 02 '21 at 16:52

0 Answers0