2 ms·
> In python methods are bound implicitly in a class, but explicitly in assignment (iirc). Oh, it's quite a bit more involved than that :) I'm going to ignore
by blattimwind 8y ago
> In python methods are bound implicitly in a class, but explicitly in assignment (iirc).
Oh, it's quite a bit more involved than that :)
I'm going to ignore Python 2 and the C API here.
In Python functions are descriptors. This means they have (mostly) a __get__ function which returns a closure passing self or cls or nothing (corresponding to a regular method, a class method and a static method; @classmethod and @staticmethod change the implementation of __get__, but of course they don't, because everything is a special case in CPython; note that "regular methods" are "regular functions" — all functions behave like methods if you treat them like one). If you write
class Class:
def foo(self, x): print(x)
then foo is a regular old function. The magic is in the dot operator (quite literally): instance.foo is a different operator from Class.foo, and instance.foo is not Class.foo (one is a bound method the other is a plain function). The former invokes the descriptor protocol to the effect of, roughly, type(instance).__dict['foo']__.__get__(type(instance), instance), which returns a closure calling the "real foo" (Class.foo) with instance as the first argument. Similarly @classmethod has the effect of __get__ returning a different closure, which passes type(instance) as the first argument instead.
Python. It's complicated®.
- wruza 8y agoYeah, one most complex way to do it. I just tested my assertion for the sake of truth and it seems correct: class Foo: def bar(self, x): print 'bar', x def f(x): print 'f', x foo = Foo() foo.baz = f print(foo.bar) # <bound method Foo.bar of <__main__.Foo object>> print(foo.baz) # <function f> foo.bar(5) # bar 5 foo.baz(6) # f 6 Now who wants to say that 'js this' is quirky and complicated?