目前,我倾向于超级类(Exposed)定义 a静态方法,这是一个装饰器(暴露),任何派生的 class可以使用@Exposed.expose标记一个方法,然后它将被getExposedMethods()返回 ,一个la: 类暴露: @staticmethod def揭示(f): ... def getExposedMethods(self ): ... 类人物(暴露): @ Exposed.expose def talk(self,...): ... 我正试图通过填充静态来实现装饰器 成员列表中包含该方法的任何类。 getExposedMe然后thods()会将每个 列表的内容从自身返回到类层次结构中的Exposed。第一个 问题是有一个方法的引用(即talk())确实 不允许你获得对封闭类的引用(我曾希望 im_class会引导我去那里)。 I''m developing a library at the moment that involves many classes, some of which have "exposed" capabilities. I''m trying to design a nice interface for both exposing those capabilities, and inspecting instances to find out what capabilities they have. At the moment, I''m leaning towards a superclass (Exposed) that defines a static method which is a decorator (expose) such that any derived class can mark a method with @Exposed.expose and it will then be later returned by getExposedMethods(), a la: class Exposed: @staticmethod def expose( f ): ... def getExposedMethods( self ): ... class Person( Exposed ): @Exposed.expose def talk( self, ... ): ... I''m trying to implement the decorator by having it populate a static member list of whatever class it''s in with a reference to the method. getExposedMethods() would then return the contents of each of those lists from itself back to Exposed in the class hierarchy. The first problem was that having a reference to the method (i.e. talk()) does not allow you to get a reference to the enclosing class (I had hoped im_class would lead me there). 还没有。当你的装饰者被调用时,类对象还没有被创建,你正在装饰的是一个简单的函数。Not yet. When your decorator is called, the class object is not yetcreated, and what you are decorating is a plain function. 真实的打嗝是那个明确的 将类作为参数传递给装饰器会产生一个未定义的 全局名称错误,大概是因为在那个执行点上 类对象尚未完全创建/初始化。 The real hiccup was that explicitly passing the class as an argument to the decorator generates a undefined global name error, presumably because at that point of execution the class object hasn''t been fully created/initialised. 确实。Exactly. 那么怎么办呢? So how can this be done? 最简单的方法是使用两阶段方案:将函数标记为 暴露,然后收集它们: def expose(func): func._exposed = True return func def exposed(obj): 返回callable(obj)和getattr(obj,''_ expposed'',False) class Exposing(object): @classmethod def get_exposed_methods(cls): 试试: exposeds = cls._exposed_methods 除了AttributeError: exposeds = [] dir(cls)中的名字: obj = getattr(cls,name ) 如果暴露(obj): exposeds.append(obj) cls._exposed_methods = exposeds 返回暴露 类鹦鹉(曝光): @expose def parrot(self,what): 返回"%s表示%s" %(self,str(what)) HTH - bruno desthuilliers python -c" print''@''。join([''。''。join([w [:: - 1] for w in p.split(''。'')])for '$ *** $ bp in''o **** @ xiludom.gro''。split(''''')])"The simplest thing is to use a two-stages scheme : mark the functions asexposed, then collect them:def expose(func): func._exposed = True return funcdef exposed(obj): return callable(obj) and getattr(obj, ''_exposed'', False)class Exposing(object): @classmethod def get_exposed_methods(cls): try: exposeds = cls._exposed_methods except AttributeError: exposeds = [] for name in dir(cls): obj = getattr(cls, name) if exposed(obj): exposeds.append(obj) cls._exposed_methods = exposeds return exposedsclass Parrot(Exposing): @expose def parrot(self, what): return "%s says %s" % (self, str(what))HTH--bruno desthuillierspython -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) forp in ''o****@xiludom.gro''.split(''@'')])" 谢谢Bruno。我今天在工作中提出了类似的解决方案,其中涉及一个''init''方法,在每个模块的底部调用 定义Exposed的子类并为 公开方法设置静态映射。我想我的解决方案稍微不那么优雅,因为 它需要在类b / b 实际处理的类之外进行这种丑陋的显式init调用,但是它更有效因为dir( ) 传递一次在模块加载时发生,而不是每次我想要列表 暴露方法。 谢谢你尽管如此, GlenThanks Bruno. I came up with a similar solution today at work, whichinvolves an ''init'' method which is called at the bottom of each modulethat defines subclasses of Exposed and sets up static mappings for theexposed methods. I guess my solution is slightly less elegant becauseit requires this ugly explicit init call outside the classes that itactually deals with, however it is more efficient because the dir()pass happens once on module load, instead of every time I want the listof exposed methods.Thanks for the help though,Glen Le jeudi 05 octobre 2006 17:18, GL ****************** @ gmail.com écrit*:Le jeudi 05 octobre 2006 17:18, gl******************@gmail.com a écrit*: 我想我的解决方案稍微不那么优雅因为 它需要在类之外进行这种丑陋的显式init调用 实际上处理,但它更有效,因为dir() 传递在模块加载时发生一次,而不是每次我想要列表 暴露方法。I guess my solution is slightly less elegant becauseit requires this ugly explicit init call outside the classes that itactually deals with, however it is more efficient because the dir()pass happens once on module load, instead of every time I want the listof exposed methods. 您总是可以使用 元类替换类上的init方法。 这用布鲁诺的曝光装饰器演示了它,但它也可以用 你的实际初始化函数来完成。 在[6]中: class m(type): ...:def __init __(self,* a,** kw): ...:for name,meth in self。 __dict __。items(): ...:如果getattr(meth,''_ expposed'',False): ...:print''exposed:' ',名字 ......: ......: 在[7]中:a类(对象): ...:__ metaclass__ = m ...:def f(self):pass ...:@expose ...:def g(self):传递 ...: ......: 暴露:g 在[8]中:b(a)类: ...:@expose ... :def h(self):传递 ...: ...: 暴露:h - _____________ Maric Michaud _____________ 亚里士多德 - www.aristote.info 3 place des tapis 69004里昂 电话:+33 426 880 097You can always replace the need of the init method on classes using ametaclass.This demonstrates it with Bruno''s expose decorator, but it can be done withyour actual init func too.In [6]: class m(type) :...: def __init__(self, *a,**kw) :...: for name, meth in self.__dict__.items() :...: if getattr(meth, ''_exposed'', False) :...: print ''exposed :'', name...:...:In [7]: class a(object):...: __metaclass__ = m...: def f(self) :pass...: @expose...: def g(self) :pass...:...:exposed : gIn [8]: class b(a) :...: @expose...: def h(self) :pass...:...:exposed : h--_____________Maric Michaud_____________Aristote - www.aristote.info3 place des tapis69004 LyonTel: +33 426 880 097 这篇关于从方法装饰器内部访问静态成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 09-02 18:23