Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Gregory Ewing Newsgroups: comp.lang.python Subject: Re: [Python-Dev] Dinamically set __call__ method Date: Sun, 09 Nov 2014 11:31:13 +1300 Lines: 60 Message-ID: References: <545919B6.7040007@stoneleaf.us> <87a943qyvn.fsf@handshake.de> <545CC204.2010301@stoneleaf.us> <8761eq424e.fsf@handshake.de> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net 3P6CKQDaJfd8SV3mj/KoQgMVcPIX6jJlvNkG/XQuKXAWrWrK9r Cancel-Lock: sha1:6zjJ9GnqN2jKB+m8vKoBsbokYrE= User-Agent: Mozilla Thunderbird 1.0.5 (Macintosh/20050711) X-Accept-Language: en-us, en In-Reply-To: Xref: csiph.com comp.lang.python:80407 Ethan Furman wrote: >> >>> On 11/06/2014 10:59 PM, dieter wrote: >>> >>>> A possibility to get the original approach implemented looks like: >>>> >>>> make "__call__" a descriptor on the class which looks up the real >>>> method on the instance. >>> >>> This still wouldn't get the signatrue correct, though. >> >> Why not? Once the descriptor is resolved, you get the final >> instance method - with the correct signature. > > Hmmm... well, it wouldn't be correct on a class lookup, but, yeah, it > would be correct for an instance lookup -- and maybe that's good enough > for the OP. Seems to depend on how you get hold of the object you're inspecting the signature of. I did an experiment: class C(object): @property def __call__(self): return self.call def f(x, y): print("Called f with %s, %s" % (x, y)) c = C() c.call = f c(17, 42) prints: Called f with 17, 42 This works too: import inspect print(inspect.getargspec(c.__call__)) prints: ArgSpec(args=['x', 'y'], varargs=None, keywords=None, defaults=None) But print(inspect.getargspec(c)) doesn't work: TypeError: <__main__.C object at 0x479250> is not a Python function (BTW, I'm actually surprised that this technique makes c callable. There must be more going on that just "look up __call__ in the class object", because evaluating C.__call__ just returns the descriptor and doesn't invoking the descriptor mechanism.) -- Greg