super,decorators和gettattribute [英] super, decorators and gettattribute

查看:56
本文介绍了super,decorators和gettattribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我正在玩Python的对象系统和装饰器而且我决定写一下(作为练习)
一个装饰器(如果应用于

方法)会在

做任何事情之前调用同名的超类方法(最初我想做一些像CLOS

[1]:之前和:结束方法,但结果太难了

很难)。


然而,我不能正确(特别是,摆脱eval)。我怀疑我可能会误解

超级对象和__getattribute__方法之间发生的事情。


这是我的代码:


def endmethod(有趣):

"""装饰师,首先调用超类''有趣。

如果类child和parent定义如下,它应该像

一样工作:

< blockquote class =post_quotes>
>> x = child()
x.foo()



我是父母的foo

我是孩子的foo。

"""

name =有趣.__ name__

def装饰(自我,* args,** kwargs):

尝试:

super_object = super(self .__ class__,自我)


#现在我想达到相当于调用的东西

#parent.foo(* args,** kwargs)

#如果我想仅限于此例子


#这不起作用:在这个例子中,它调用了孩子的foo,

#进入一个永恒的循环(而不是叫做父母的'

#foo,正如我所料。)


#super_object .__ getattribute __(name)(* args,** kwargs)


#这确实有效,但我觉得它很丑陋

eval(''super_object。%s(* args,** kwargs)'' %name)

除了AttributeError:

传递#如果父母没有实现乐趣,我们不在乎

#关于它

返回乐趣(自我,* args,** kwargs)#hopefully none


装饰.__ name__ =名称

返回装饰

班级父母(对象):

def foo(个体经营):

打印''我是父母\\'''foo''


班级孩子(父母):

@endmethod

def foo(self):

打印我是foo \'的foo。


如果__name __ ==''__ main__'':

x = child()

x.foo()


有人能告诉我如何调用超类方法知道它的名字吗?


先谢谢,

- Richard


[1] http://en.wikipedia.org/wiki/Common_Lisp_Object_System

解决方案

1月12日晚上7:45,Richard Szopa< ryszard.sz ... @ gmail.comwrote:


做任何事情(最初我想要的)做一些像CLOS

[1]:之前和:结束方法,但事实证明太难了b / b
很难)。



嗯,我的意思是:之前和之后:方法之后。


- Richard


2008年1月12日星期六10:45:25 -0800(太平洋标准时间)Richard Szopa< ry *********** @ gmail.comwrote:


Hello all,


我正在玩Python的对象系统和装饰器而且我

决定写(作为练习)装饰者(如果应用于

方法)将在

之前调用超类''同名方法什么(最初我想做一些像CLOS

[1]:之前和:结束方法,但事实证明太难了

困难)。


然而,我无法做到正确(特别是,摆脱了eval)。我怀疑我可能会误解

超级对象和__getattribute__方法之间发生的事情。


这是我的代码:


def endmethod(有趣):

"""装饰师,首先调用超类''有趣。

如果类child和parent定义如下,它应该像

一样工作:


>> x =儿童()

>> x.foo()



I我是父母的foo

我是孩子的foo。

"""

name = fun .__ name __

def装饰(自我,* args,** kwargs):

尝试:

super_object = super(self .__ class__,self)



这里有一个明显常见的错误:你不想传递超级

self .__ class__,但是他把这个方法绑定到了这个类。两个

是不一样的,因为子类的实例将子类

作为self .__ class__,而不是当前的类。所以super会返回

当前类或它的子类,这意味着(因为你从self调用了这个

方法),你最终会递归地调用这个方法。

所有这些都意味着你的装饰师可能不得不把这个类作为一个参数。


#现在我想要达到相当于调用的东西

#parent.foo(* args,** kwargs)

#如果我想将它限制在这个例子中


#这不起作用:在这个例子中,它调用了孩子的foo,

#进入一个永恒的循环(而不是调用父母的

#foo,正如我所料)。


#super_object .__ getattribute __(name)(* args,** kwargs)


#这确实有效,但我觉得它很丑陋

eval(''super_object。%s(* args,** kwargs) ''%name)

除了AttributeError:

传递#如果父母没有实现乐趣,我们不在乎

#关于它

返回乐趣(自我,* args,** kwargs)#hopefully none


装饰.__ name__ = name

返回装饰


班级父母(对象):

def foo(self):

print''我是父母''foo''


班级孩子(父母):

@endmethod

def foo(self):

print"我很好foo。


if __name __ ==''__ main__'':

x = child()

x.foo()


有人能告诉我如何调用超类方法知道它的名字吗?



如果您知道它的名字,就像调用任何对象的方法一样:


getattr (super_object,name)(* args,** kwargs)


代码似乎按照你想要的方式工作:


>> x.foo()



我是父母的'foo

我是foo'的foo。


< mike

-

Mike Meyer< mw*@mired.org> http://www.mired.org/consulting.html

独立网络/ Unix / Perforce顾问,电子邮件以获取更多信息。


1月12日9:47 pm,Mike Meyer< mwm-keyword- python.b4b ... @ mired.org>

写道:


如果你调用任何对象的方法的方式相同知道它的名字":


getattr(super_object,name)(* args,** kwargs)



非常感谢你的回答!


然而,我很惊讶地得知


super_object .__ getattr __(name)(* args, ** kwargs)


getattr(super_object,name)(* args,** kwargs)


不等价。这很奇怪,至少在使用len()

和.__ len __,str()和.__ str__时。你可能知道没有遵循getattr的惯例背后的理由是什么?


祝你好运,


- Richard


Hello all,

I am playing around w/ Python''s object system and decorators and I
decided to write (as an exercise) a decorator that (if applied to a
method) would call the superclass'' method of the same name before
doing anything (initially I wanted to do something like CLOS
[1] :before and :end methods, but that turned out to be too
difficult).

However, I cannot get it right (specially, get rid of the eval). I
suspect that I may be misunderstanding something happening between
super objects and __getattribute__ methods.

Here''s my code:

def endmethod(fun):
"""Decorator to call a superclass'' fun first.

If the classes child and parent are defined as below, it should
work like:

>>x = child()
x.foo()

I am parent''s foo
I am child''s foo.
"""
name = fun.__name__
def decorated(self, *args, **kwargs):
try:
super_object = super(self.__class__, self)

# now I want to achieve something equivalent to calling
# parent.foo(*args, **kwargs)
# if I wanted to limit it only to this example

# this doesn''t work: in the example, it calls child''s foo,
# entering in an eternal loop (instead of calling parent''s
# foo, as I would expect).

# super_object.__getattribute__(name)(*args, **kwargs)

# this does work, but I feel it''s ugly
eval(''super_object.%s(*args, **kwargs)'' % name)
except AttributeError:
pass # if parent doesn''t implement fun, we don''t care
# about it
return fun(self, *args, **kwargs) # hopefully none

decorated.__name__ = name
return decorated
class parent(object):
def foo(self):
print ''I am parent\''s foo''

class child(parent):
@endmethod
def foo(self):
print "I am foo\''s foo."

if __name__==''__main__'':
x = child()
x.foo()

Can anybody tell me how to call a superclass method knowing its name?

Thanks in advance,
-- Richard

[1] http://en.wikipedia.org/wiki/Common_Lisp_Object_System

解决方案

On Jan 12, 7:45 pm, Richard Szopa <ryszard.sz...@gmail.comwrote:

doing anything (initially I wanted to do something like CLOS
[1] :before and :end methods, but that turned out to be too
difficult).

Erm, I meant :before and :after methods.

-- Richard


On Sat, 12 Jan 2008 10:45:25 -0800 (PST) Richard Szopa <ry***********@gmail.comwrote:

Hello all,

I am playing around w/ Python''s object system and decorators and I
decided to write (as an exercise) a decorator that (if applied to a
method) would call the superclass'' method of the same name before
doing anything (initially I wanted to do something like CLOS
[1] :before and :end methods, but that turned out to be too
difficult).

However, I cannot get it right (specially, get rid of the eval). I
suspect that I may be misunderstanding something happening between
super objects and __getattribute__ methods.

Here''s my code:

def endmethod(fun):
"""Decorator to call a superclass'' fun first.

If the classes child and parent are defined as below, it should
work like:

>>x = child()
>>x.foo()

I am parent''s foo
I am child''s foo.
"""
name = fun.__name__
def decorated(self, *args, **kwargs):
try:
super_object = super(self.__class__, self)

There''s an apparently common bug here: you don''t want to pass super
self.__class__, but the class that the method is bound to. The two
aren''t the same, as an instance of a subclass will have the subclass
as self.__class__, and not the current class. So super will return the
current class or a subclass of it, meaning (since you invoked this
method from self) you''ll wind up invoking this method recursively.
All of which means your decorator is probably going to have to take
the class as an argument.

# now I want to achieve something equivalent to calling
# parent.foo(*args, **kwargs)
# if I wanted to limit it only to this example

# this doesn''t work: in the example, it calls child''s foo,
# entering in an eternal loop (instead of calling parent''s
# foo, as I would expect).

# super_object.__getattribute__(name)(*args, **kwargs)

# this does work, but I feel it''s ugly
eval(''super_object.%s(*args, **kwargs)'' % name)
except AttributeError:
pass # if parent doesn''t implement fun, we don''t care
# about it
return fun(self, *args, **kwargs) # hopefully none

decorated.__name__ = name
return decorated
class parent(object):
def foo(self):
print ''I am parent\''s foo''

class child(parent):
@endmethod
def foo(self):
print "I am foo\''s foo."

if __name__==''__main__'':
x = child()
x.foo()

Can anybody tell me how to call a superclass method knowing its name?

The same way you call any object''s methods if you know it''s name":

getattr(super_object, name)(*args, **kwargs)

The code seems to work the way you want:

>>x.foo()

I am parent''s foo
I am foo''s foo.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.


On Jan 12, 9:47 pm, Mike Meyer <mwm-keyword-python.b4b...@mired.org>
wrote:

The same way you call any object''s methods if you know it''s name":

getattr(super_object, name)(*args, **kwargs)

Thanks a lot for your answer!

However, I am very surprised to learn that

super_object.__getattr__(name)(*args, **kwargs)

getattr(super_object, name)(*args, **kwargs)

are not equivalent. This is quite odd, at least when with len()
and .__len__, str() and .__str__. Do you maybe know what''s the
rationale behind not following that convention by getattr?

Best regards,

-- Richard


这篇关于super,decorators和gettattribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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