Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Ian Kelly Newsgroups: comp.lang.python Subject: Re: Can I find the class of a method in a decorator. Date: Sat, 5 Mar 2016 18:07:02 -0700 Lines: 71 Message-ID: References: <56DAF5A7.9080503@rece.vub.ac.be> <56DB0779.5040409@rece.vub.ac.be> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de /6Vs3hqltR7VKYUoNVQqwA+kEB4MAHXTS/MMqbkw9bFg== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.003 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'else:': 0.03; 'received:209.85.223': 0.03; 'run,': 0.07; 'attribute.': 0.09; 'cmd': 0.09; 'extern': 0.09; 'subject:method': 0.09; 'python': 0.10; 'def': 0.13; 'appropriate': 0.14; 'argument': 0.15; '...)': 0.16; '2016': 0.16; 'boolean': 0.16; 'called,': 0.16; 'descriptor.': 0.16; 'metaclass': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'subject:class': 0.16; 'wrote:': 0.16; 'string': 0.17; 'attribute': 0.18; '>>>': 0.20; 'work,': 0.21; 'decorator': 0.22; 'suppose': 0.22; 'trying': 0.22; 'am,': 0.23; 'sat,': 0.23; 'header:In-Reply-To:1': 0.24; "doesn't": 0.26; 'chris': 0.26; 'external': 0.27; 'not.': 0.27; 'message- id:@mail.gmail.com': 0.27; 'function': 0.28; 'idea': 0.28; 'idea?': 0.29; 'raise': 0.29; 'work.': 0.30; 'class.': 0.30; 'candidate': 0.31; 'anybody': 0.32; 'class': 0.33; 'problem': 0.33; 'though.': 0.33; 'add': 0.34; 'received:google.com': 0.35; 'could': 0.35; 'something': 0.35; "isn't": 0.35; 'needed': 0.36; 'there': 0.36; 'received:209.85': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'method': 0.37; 'wanted': 0.37; '(with': 0.38; 'received:209': 0.38; 'subject:the': 0.39; "didn't": 0.39; 'rather': 0.39; 'to:addr:python.org': 0.40; 'called': 0.40; 'some': 0.40; 'your': 0.60; 'mar': 0.65; 'obvious': 0.76; 'sounds': 0.76; 'angelico:': 0.84; 'chrisa': 0.84; "class's": 0.84; 'pardon': 0.84; 'schreef': 0.84; 'to:name:python': 0.84; 'subject:find': 0.91; 'try.': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=fqNEvHZThAHEubQW/gRgDfyLnjzFLuQ/00fW2ezjNEE=; b=ZA7Gub3ZRY+NCo/53FO7t94jRZ/VFHcyLTW+kxsV60fTxpCEuc19gJp1plqOQBucWY oD55BAD11cbax2V/oIFOXmBswm+WQKEVbo6AD8Y8DjPRpCiCHzxlWj4khLFqFCxINUZ9 D+dmfHStG32mTXjfbsASn/n3+qDWhhl4RABtH0aBvcfLaoLpwwtYHcRP0bhvzjp+kJWT tBKgf1kseEcrg4dXj9DI04fZKy4CzvVR00Mapmj7TYeErLD5RhhM9fXcJDR3l5cE8Tsg xmei8mJiMq7KeTl9Acs8l7GWPYEmqAR90talWXJOSOnUXBkJ2vtzEoN1UANaYjIcCLdR MGsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=fqNEvHZThAHEubQW/gRgDfyLnjzFLuQ/00fW2ezjNEE=; b=dme4w3jN+4jTBjtIxW2KucVkl8EucjV29+x1phPLwDxIIdr1Xh0xVW2JnJwhRmDGht AE0ODM+2wM5w3pyuqD9ozmJFzIivuKuPqA8G+Lywz4KCD02RWcDPvyrpiAjLkJQefnUm jJHqFxq+lILwLRfKQcxG6IwECJTUDoh8iS/Ab4rFRXDjhCJUcimJ5+4mq9aoGnQpLDKd ltXFZzTUM3TCqKz05ViWRwTPfbZbae9sli9qz8ElzHgYfy3/5y+jsk6ukgGrfE+KrFgJ BPh7zLNAOyY4W4K9b0MSppUWzTklbdAq8929DqOkCr6O9NFumFF64BrUszsQCj+lFi5e ii7w== X-Gm-Message-State: AD7BkJKV0Vs6hA6Fw1JteXxSbF27vuTW2uFOjGlgQftZDkc/YUWSSto8N7at4YhY2jP8yLDlRdH5NT05fNyNjg== X-Received: by 10.107.19.140 with SMTP id 12mr12721446iot.11.1457226461673; Sat, 05 Mar 2016 17:07:41 -0800 (PST) In-Reply-To: <56DB0779.5040409@rece.vub.ac.be> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:104117 On Sat, Mar 5, 2016 at 9:21 AM, Antoon Pardon wrote: > Op 05-03-16 om 16:18 schreef Chris Angelico: >> On Sun, Mar 6, 2016 at 2:05 AM, Antoon Pardon >> wrote: >>> Using python 3.4/3.5 >>> >>> Suppose I have the following class: >>> >>> class Tryout: >>> >>> @extern >>> def method(self, ...) >>> >>> Now how can I have access to the Tryout class in >>> the extern function when it is called with method >>> as argument >>> >>> def extern(f): >>> the_class = ???? >>> >>> f.__class doesn't work, if I write the following >>> >>> def extern(f) >>> print(f.__class__) >>> >>> the result is: , so that doesn't work. >>> Looking around I didn't find an other obvious candidate >>> to try. Anybody an idea? >> >> At the time when the function decorator is run, there isn't any class. >> You could just as effectively create your function outside the class >> and then inject it (Tryout.method = method). >> >> What is it you're trying to do? Would it be a problem to have a class >> decorator instead/as well? >> >> ChrisA >> > > The idea is that some of these methods will be externally available > and others are not. So that I get an external string and can do > something of the following: > > tryout = Tryout() > > st = read_next_cmd() > > if st in tryout.allowed: > getattr(tryout, st)() > else: > raise ValueError("%s: unallowed cmd string" % st) > > And the way I wanted to populate Tryout.allowed as a class attribute > would have been with the decorator extern, which would just have put > the name of the method in the Tryout.allowed set and then return the function. If you only needed the function decorator to access the class when the method is called, then you could have the function decorator return a custom descriptor. It sounds like you want this to happen before the method is called, though. You could have the function decorator simply set an attribute on the function and return it. Then use a class decorator or a metaclass to scan all the class's methods when it's constructed in order to populate the allowed attribute. Alternatively you could have the function decorator add the allowed attribute as a boolean on the method rather than on the class and just check getattr(type(tryout), st).allowed (with the appropriate try-except).