1
class C():
    def print_once(self):
        print(self)

def print_twice(self):
    print(self, self)

c = C()
setattr(c, 'print_twice', print_twice)
c.print_once()
c.print_twice()
>>> <__main__.C object at 0x0000028116795108>
>>> TypeError: print_twice() missing 1 required positional argument: 'self'

I'm aware setattr(C, ..) does the trick, but this affects future and concurrent instances of C and is undesired. Can print_twice be set only to c, such that self is passed automatically just like to print_once?

OverLordGoldDragon
  • 1
  • 9
  • 53
  • 101
  • Is `print_twice` inside class `C`? – arshovon Jul 12 '20 at 13:20
  • 2
    `setattr(c, 'print_twice', functools.partial(print_twice, c))` would emulate what an actual bound method does. – jasonharper Jul 12 '20 at 13:24
  • The mechanism of passing ``self`` is related to the descriptor protocol – the TLDR is that methods *must be* on the class, by definition. A function on an instance is just a callable attribute. Why do you even *want* ``self`` to be passed automatically? ``self`` will always be ``c``, so why not do ``c.print_twice = functools.partial(print_twice, c)``? How is this related to ``setattr`` in specific? ``c.print_twice = print_twice`` would be equivalent to your code. – MisterMiyagi Jul 12 '20 at 13:33

1 Answers1

2

From this answer:

class C():
    def print_once(self):
        print(self)

def print_twice(self):
    print(self, self)

c = C()
setattr(c, 'print_twice', print_twice.__get__(c))
c.print_once()
c.print_twice()
>> <__main__.C object at 0x000002122DE7FDC8>
>> <__main__.C object at 0x000002122DE7FDC8> <__main__.C object at 0x000002122DE7FDC8>
OverLordGoldDragon
  • 1
  • 9
  • 53
  • 101