Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

method objects vs function objects , Python class instances vs class

I am trying to verify the difference between instance attributes and class attributes as laid out by the Python tutorial release 2.7.3 dated Nov 01, 2012, chapter 9: Classes, Page 66 last line (source):

Valid method names of an instance object depend on its class. By definition, all attributes of a class that are function objects define corresponding methods of its instances. So in our example, x.f is a valid method reference, since MyClass.f is a function, but x.i is not, since MyClass.i is not. But x.f is not the same thing as MyClass.f — it is a method object, not a function object.

I have this:

class MyClass:    
   """A simple example class"""    
   i = 12345   
   def f():    
      return 'hello world'

Then I do this:

>>> x = MyClass()
>>> x.f
<bound method MyClass.f of <__main__.MyClass instance at 0x02BB8968>>
>>> MyClass.f
<unbound method MyClass.f>
>>> type(MyClass.f)
<type 'instancemethod'>
>>> type(x.f)
<type 'instancemethod'>

Note that the type of both x.f and MyClass.f is instancemethod. There is no difference in types but the tutorial says otherwise. Can someone please clarify?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Bound vs Unbound Methods - an explanation.

... or why Python has the behaviour you point out.

So, first off, a note that this is different in 3.x. In 3.x, you will get MyClass.f being a function, and x.f as a method - as expected. This behaviour is essentially a poor design decision that has later been changed.

The reason for this is that Python has the concept of a method that is different to most languages, which is essentially a function with the first argument pre-filled as the instance (self). This pre-filling makes a bound method.

>>> x.foo
<bound method MyClass.foo of <__main__.MyClass instance at 0x1004989e0>>

In Python 2.x and before, it was reasoned that a method not attached to an instance would be an unbound method, which was a function with the restriction that the first argument (self), must be an instance of the object. This is then ready to be bound to an instance and become a bound method.

>>> MyClass.foo
<unbound method MyClass.foo>

With time, it became clear an unbound method is really just a function with this odd restriction that didn't really matter (that self must be of the 'correct' type), so they were removed from the language (in 3.x). This is essentially duck-typing self, which suits the language.

Python 3.3.0 (default, Dec  4 2012, 00:30:24) 
>>> x.foo
<bound method MyClass.foo of <__main__.MyClass object at 0x100858ed0>>
>>> MyClass.foo
<function MyClass.foo at 0x10084f9e0>

Further reading.

This is a (condensed, from memory) explanation which can be read in full from Python creator Guido van Rossum's own mouth in his 'History of Python' series.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...