从方法装饰器内部访问静态成员? [英] Access to static members from inside a method decorator?

查看:135
本文介绍了从方法装饰器内部访问静态成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个涉及许多课程的图书馆,其中一些图书馆已经曝光了。能力。我正在尝试设计一个漂亮的

界面,以便公开这些功能,并检查

实例以找出它们具备的功能。

目前,我倾向于超级类(Exposed)定义

a静态方法,这是一个装饰器(暴露),任何派生的

class可以使用@Exposed.expose标记一个方法,然后它将被getExposedMethods()返回

,一个la:


类暴露:< br $>
@staticmethod

def揭示(f):

...


def getExposedMethods(self ):

...

类人物(暴露):

@ Exposed.expose

def talk(self,...):

...


我正试图通过填充静态来实现装饰器

成员列表中包含该方法的任何类。

getExposedMethods()然后返回内容每个

列出自己回到类层次结构中的Exposed。第一个

问题是有一个方法的引用(即talk())确实

不允许你获得对封闭类的引用(我曾希望

im_class会引导我去那里)。真正的打嗝是明确地将
作为参数传递给装饰器会产生一个未定义的

全局名称错误,大概是因为在那个执行点上

类对象尚未完全创建/初始化。


那怎么办呢?看起来似乎不可能将封闭类的

引用传递给装饰器,而这又是

意味着静态跟踪列表暴露的方法是不可能的

(至少,如果我想使用装饰器)。


任何可以实现我的初始设计或建议的想法

优雅,可行的替代方案将不胜感激。


干杯,

Glen

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). 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.

So how can this be done? It doesn''t seem like it''s possible to pass a
reference to the enclosing class into the decorator, which in turn
means that static tracking of the list of exposed methods is impossible
(at least, if I want to use decorators).

Any ideas that will enable my initial design, or suggestions for an
elegant, workable alternative would be much appreciated.

Cheers,
Glen

推荐答案

gl ** ****************@gmail.com 写道:

我正在开发一个库涉及许多课程的那一刻,其中一些已经曝光了。能力。我正在尝试设计一个漂亮的

界面,以便公开这些功能,并检查

实例以找出它们具备的功能。

目前,我倾向于超级类(Exposed)定义

a静态方法,这是一个装饰器(暴露),任何派生的

class可以使用@Exposed.expose标记一个方法,然后它将被getExposedMethods()返回

,一个la:


类暴露:< br $>
@staticmethod

def揭示(f):

...


def getExposedMethods(self ):

...

类人物(暴露):

@ Exposed.expose

def talk(self,...):

...


我正试图通过填充静态来实现装饰器

成员列表中包含该方法的任何类。

getExposedMethods()然后返回n每个

列出的内容从自身返回到类层次结构中的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 yet
created, 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):< br $>
@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 as
exposed, then collect them:

def expose(func):
func._exposed = True
return func

def 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 exposeds

class Parrot(Exposing):
@expose
def parrot(self, what):
return "%s says %s" % (self, str(what))

HTH
--
bruno desthuilliers
python -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) for
p in ''o****@xiludom.gro''.split(''@'')])"


Bruno Desthuilliers写道:
Bruno Desthuilliers wrote:
gl **** **************@gmail.com 写道:

我正在开发一个图书馆这涉及到许多课程,其中一些课程已经曝光了。能力。我正在尝试设计一个漂亮的

界面,以便公开这些功能,并检查

实例以找出它们具备的功能。

目前,我倾向于超级类(Exposed)定义

a静态方法,这是一个装饰器(暴露),任何派生的

class可以使用@Exposed.expose标记一个方法,然后它将被getExposedMethods()返回

,一个la:


类暴露:< br $>
@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 yet
created, 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):< br $>
@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 as
exposed, then collect them:

def expose(func):
func._exposed = True
return func

def 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 exposeds

class Parrot(Exposing):
@expose
def parrot(self, what):
return "%s says %s" % (self, str(what))

HTH
--
bruno desthuilliers
python -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) for
p in ''o****@xiludom.gro''.split(''@'')])"



谢谢Bruno。我今天在工作中提出了类似的解决方案,其中
涉及一个''init''方法,在每个模块的底部调用

定义Exposed的子类并为

公开方法设置静态映射。我想我的解决方案稍微不那么优雅,因为

它需要在类b / b
实际处理的类之外进行这种丑陋的显式init调用,但是它更有效因为dir( )

传递一次在模块加载时发生,而不是每次我想要列表

暴露方法。


谢谢你尽管如此,

Glen

Thanks Bruno. I came up with a similar solution today at work, which
involves an ''init'' method which is called at the bottom of each module
that defines subclasses of Exposed and sets up static mappings for the
exposed methods. I guess my solution is slightly less elegant because
it requires this ugly explicit init call outside the classes that it
actually deals with, however it is more efficient because the dir()
pass happens once on module load, instead of every time I want the list
of 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 because
it requires this ugly explicit init call outside the classes that it
actually deals with, however it is more efficient because the dir()
pass happens once on module load, instead of every time I want the list
of 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 097

You can always replace the need of the init method on classes using a
metaclass.

This demonstrates it with Bruno''s expose decorator, but it can be done with
your 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 : g

In [8]: class b(a) :
...: @expose
...: def h(self) :pass
...:
...:
exposed : h


--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097


这篇关于从方法装饰器内部访问静态成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆