MethodType / FunctionType和装饰器 [英] MethodType/FunctionType and decorators

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

问题描述

大家好!


我对Python很陌生,所以如果我错过请原谅我

。最近,我一直在和装饰师一起玩,而且我对某些行为感到困惑。下面的代码让我感到困惑:


在python shell中:


def函数():

通过


A级(对象):

def方法(个体经营):

传递


from types import MethodType

from types import FunctionType


如果type(function)是FunctionType:

print"这就是我所期望的


如果类型(A.method)是MethodType:

print"这就是我所期望的


到目前为止一切都那么好......一切看起来都合乎逻辑。


但是如果宣布装饰者的事情变得与众不同:


def deco(函数):

如果type(function)是MethodType:

print" MethodType"

elif type(function )是FunctionType:

print" FunctionType"

@deco

def function2():

通过


#==这打印出FunctionType(oke)


A级(o bject):

@deco

def方法(个体经营):

通过


#= =这打印出FunctionType(???)


有人可以解释为什么我会看到这个吗?


(使用Python 2.5) .1在Win XP上)。


TIA,


../alex

-

..w(the_mindstorm)p。

解决方案

7月5日上午1:52,Alex Popescu< ; the.mindstorm.mailingl ... @ gmail.com>

写道:


大家好!

我对Python很陌生,所以如果我错过了请原谅我

。最近,我一直在和装饰师一起玩,而且我对某些行为感到困惑。下面的代码让我感到困惑:


在python shell中:


def函数():

通过


A级(对象):

def方法(个体经营):

传递


from types import MethodType

from types import FunctionType


如果type(function)是FunctionType:

print"这就是我所期望的


如果类型(A.method)是MethodType:

print"这就是我所期望的


到目前为止一切都那么好......一切看起来都合乎逻辑。


但是如果宣布装饰者的事情变得与众不同:


def deco(函数):

如果type(function)是MethodType:

print" MethodType"

elif type(function )是FunctionType:

print" FunctionType"

@deco

def function2():

通过


#==这打印出FunctionType(oke)


A级(对象):

@deco

def方法(个体经营):

传递

#==这打印出FunctionType(???)


有人能说清楚为什么我会看到这个吗?


(在Win XP上使用Python 2.5.1)。


TIA,


./alex

-

.w(the_mindstorm)p。



首先我应该更正我的例子使用

isinstance(function_or_method,builtin_factory_function)。


其次,我想发生了以下情况:


- 当从类定义外部进行测试时,函数已经附加到了b / b
类实例,这就是为什么它的

类型是instancemethod

- 对于装饰器,我的测试是在定义类之前执行的,并且

所以那时功能仍然是一个功能;只有在关闭类定义后它才会成为

方法实例


这是正确的还是我只是在这里制作?


TIA,


../alex

-

..w(the_mindstorm)p。


Alex Popescu< th *********************** @ gmail.comwrote:

...


- 从类定义外部进行测试时,函数已经附加到类实例并且已经附加到类实例上了这就是为什么它的

类型是instancemethod



更确切地说:当你访问某个类的任何属性时(或者

其实例),Python检查该属性是否是描述符(即

属性的类型有__get__方法 - 有更好的

基于它是否也有一个__set__方法的区别,即是或者不是b $ b isn''ta数据描述符,但它们不会来在这里玩。


一个函数的类型确实有一个__get__方法,IOW每个

(Python编码)函数都是一个描述符(非-data one,btw)。


所以,当你访问Cf,其中C是一个类而f'的类型是Python编码的

函数,你得到在该f对象上调用__get__的结果

本身。那些结果是......信封,拜托!... ta-da:一个新的

铸造方法对象(其im_func为f)。


- 对于装饰者,我的测试在定义类之前执行,并且

所以此时函数仍然是一个函数;只有在类定义关闭后它才会成为一个

方法实例



函数对象永远不会成为方法对象;它将保持一个

函数对象(你可以使用C .__ dict __ [''f'']来获取

例子);但是如果您将该名称作为C的属性(或者是C的一个

实例),例如作为Cf或getattr(C,''f''),f .__ get__将被称为

(并返回一个新编的方法对象,其im_func为f)。


这是正确的还是我只是在这里制作?



你有大致正确的想法(就装饰者而言),

只是对功能对象之间关系的略微倾斜的看法

和方法对象,我希望我帮助澄清。


以下是一些我曾经说过的玩具级示例,我希望他们

可以进一步帮助您理解功能与方法问题:


>> def f():传递



....


>> class C(object):pass



....


>> a = Cf



回溯(最近一次调用最后一次):

文件"< stdin>",第1行,< module>

AttributeError:类型对象''C''没有属性''f''


> ;> Cf = f
a = Cf
b = Cf
a == b



True


>> a是b



False


> ;>类型(a),类型(b)



(< type''instancemethod''>,<类型''instancemethod''>)


>> a.im_func,b.im_func



(< function f at 0x66030> ,<函数f在0x66030>)


>> a.im_func是f是b.im_func



True

< blockquote class =post_quotes>
>> c = f .__ get __(C)
type(c)



< type''instancemethod''>


>> c.im_func



< function f at 0x66030>


>> c.im_func是C .__ dict __ [''f'']是f



True

Alex


Alex Popescu写道:


- 对于装饰者,我的测试在定义类之前执行,并且

所以此时函数是还是一个功能;只有在关闭类定义后,它才会成为

方法实例



更接近,但仍然不太正确。即使在定义了这个类

之后,其中的函数仍然只是一个普通的函数。你可以看看



A .__ dict __ [''方法'']


An instancemethod只在你在一个实例中查看

方法时创建,即


a = A()

a.method


instancemethod封装了''self''的值和

a对底层函数的引用。这是已知的

作为绑定方法。


(如果你看方法,你也会得到一个实例方法

在课堂上,即


A.method


但在这种情况下,实例方法不包含
$ b ''self''的$ ba值,被称为未绑定

方法。)


-

Greg


Hi all!

I am pretty new to Python, so please excuse me if I am missing
something. Lately, I''ve been playing with decorators and I am a bit
confused about some behavior. Here is the code that puzzles me:

in python shell:

def function():
pass

class A(object):
def method(self):
pass

from types import MethodType
from types import FunctionType

if type(function) is FunctionType:
print "this is what I expect"

if type(A.method) is MethodType:
print "this is what I expect"

so far so good... everything seems logical.

But if a decorator is declared things are becoming different:

def deco(function):
if type(function) is MethodType:
print "MethodType"
elif type(function) is FunctionType:
print "FunctionType"

@deco
def function2():
pass

# ==this prints out FunctionType (oke)

class A(object):
@deco
def method(self):
pass

# ==this prints out FunctionType (???)

Can somebody shed some light on why I am seeing this?

(Using Python 2.5.1 on Win XP).

TIA,

../alex
--
..w( the_mindstorm )p.

解决方案

On Jul 5, 1:52 am, Alex Popescu <the.mindstorm.mailingl...@gmail.com>
wrote:

Hi all!

I am pretty new to Python, so please excuse me if I am missing
something. Lately, I''ve been playing with decorators and I am a bit
confused about some behavior. Here is the code that puzzles me:

in python shell:

def function():
pass

class A(object):
def method(self):
pass

from types import MethodType
from types import FunctionType

if type(function) is FunctionType:
print "this is what I expect"

if type(A.method) is MethodType:
print "this is what I expect"

so far so good... everything seems logical.

But if a decorator is declared things are becoming different:

def deco(function):
if type(function) is MethodType:
print "MethodType"
elif type(function) is FunctionType:
print "FunctionType"

@deco
def function2():
pass

# ==this prints out FunctionType (oke)

class A(object):
@deco
def method(self):
pass

# ==this prints out FunctionType (???)

Can somebody shed some light on why I am seeing this?

(Using Python 2.5.1 on Win XP).

TIA,

./alex
--
.w( the_mindstorm )p.

First of all I should correct my example to use
isinstance(function_or_method, builtin_factory_function).

Secondly, I guess what is happening is the following:

- when testing from outside the class definition, the function is
already attached to the class instance and this is the reason why its
type is instancemethod
- for decorators, my test is executed before the class is defined and
so at that moment the function is still a function; it will become a
methodinstance only after the class definition is closed

Is this correct or am I just fabulating here?

TIA,

../alex
--
..w( the_mindstorm )p.


Alex Popescu <th***********************@gmail.comwrote:
...

- when testing from outside the class definition, the function is
already attached to the class instance and this is the reason why its
type is instancemethod

To be more precise: when you access any attribute of a class (or
instance thereof), Python checks if that attribute is a descriptor (i.e.
the attribute''s type has a __get__ method -- there are finer
distinctions based on whether it also has a __set__ method, i.e. is or
isn''t a "data descriptor", but they don''t come into play here).

A function does have in its type a __get__ method, IOW every
(Python-coded) function is a descriptor (a non-data one, btw).

So, when you access C.f where C is a class and f''s type is Python-coded
function, you get the results of calling __get__ on that f object
itself. Those results are... the envelope, please!... ta-da: a newly
minted method object (whose im_func is f).

- for decorators, my test is executed before the class is defined and
so at that moment the function is still a function; it will become a
methodinstance only after the class definition is closed

The function object will never become a method object; it will remain a
function object (and you can get at it with C.__dict__[''f''] for
example); but if you access that name as an attribute of C (or of an
instance of C), e.g. as C.f or getattr(C, ''f''), f.__get__ will be called
(and return a freshly minted method object whose im_func is f).

Is this correct or am I just fabulating here?

You have roughly the right idea (as far as decorators are concerned),
just a slightly skewed vision of the rapport between function objects
and method objects, which I hoped I helped clarify.

Here are a few toy-level examples of what I''ve been saying, I hope they
can further help your understanding of function vs method issues:

>>def f(): pass

....

>>class C(object): pass

....

>>a=C.f

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object ''C'' has no attribute ''f''

>>C.f = f
a=C.f
b=C.f
a == b

True

>>a is b

False

>>type(a), type(b)

(<type ''instancemethod''>, <type ''instancemethod''>)

>>a.im_func, b.im_func

(<function f at 0x66030>, <function f at 0x66030>)

>>a.im_func is f is b.im_func

True

>>c=f.__get__(C)
type(c)

<type ''instancemethod''>

>>c.im_func

<function f at 0x66030>

>>c.im_func is C.__dict__[''f''] is f

True
Alex


Alex Popescu wrote:

- for decorators, my test is executed before the class is defined and
so at that moment the function is still a function; it will become a
methodinstance only after the class definition is closed

Closer, but still not quite right. Even after the class
is defined, the function sitting inside it is still
just an ordinary function. You can see this by looking
at

A.__dict__[''method'']

An instancemethod is only created when you look the
method up in an instance, i.e.

a = A()
a.method

The instancemethod encapsulates a value for ''self'' and
a reference to the underlying function. This is known
as a "bound method".

(You also get an instancemethod if you look the method
up in the class, i.e.

A.method

but in that case the instancemethod doesn''t contain
a value for ''self'', and is known as an "unbound
method".)

--
Greg


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

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