On Sat, Feb 17, 2007 at 02:04:18AM -0800, Erzengel des Lichtes wrote:
> As you can see, changing the variable on the class type changes it on all
> unchanged instances and new instances.

This isn't quite correct - Python isn't actually going through and
changing every instance.  Attribute lookup ordinarily works on an
instance by first looking for a value in the instance, then in the
class, then in superclasses if any.

> Now, I did this:
> class MyClass:
>   pass
> def Method():
>   print "hello"
> Test = MyClass()
> Test.Func1 = Method
> Test.Func1()
> MyClass.Func2 = Method
> Test.Func2()
> 
> Func1 prints out Hello, but Func2 says "TypeError: Method() takes exactly 0
> arguments (1 given)". 
> 
> Why does Func1 work? Shouldn't it be passing in Test, and so providing more
> arguments than Method wants? Why does it only do this with Func2? Why would
> assigning a function to an instance variable cause this behavior to be
> different from a class variable? 

You've discovered the difference between bound and unbound methods.
You can see it if you examine a method when it's accessed via a class
and its instance:

>>> class C(object):
...     def meth(self): return 5
... 
>>> inst = C()
>>> C.meth
<unbound method C.meth>
>>> inst.meth
<bound method C.meth of <C object at 0x000000000000002B>>
>>> C.meth()
Traceback (most recent call last):
TypeError: meth() takes exactly 1 argument (0 given)
>>> C.meth(inst)
5
>>> inst.meth()
5

Unbound methods require you specify the instance as an argument,
typically named 'self'; bound methods have an instance already bound
to 'self', hence the name.  When you define a method on a class, what
actually gets stored in the class is a "method descriptor" which
dispenses either a bound or unbound method based on the object
(instance or class, respectively) whose attribute is being looked up.

There's some more information on how lookup works (in CPython, so the
internals aren't quite valid for IronPython, but the behavior is the
same) in PEP 252:

        <http://www.python.org/dev/peps/pep-0252/>

> Is there any way to have the Func1 behavior, while being able to assign the
> change to all unchanged instances and new instances like I can with other
> variables? It's not something I really need to do, but I need to know
> Python's behavior in order to ensure I reproduce it correctly (My co-workers
> could get around any issues, but this is intended for the end user to have
> available as well, and having it act differently from CPython, IronPython,
> and others would be a Bad ThingT).

I'd suggest, having recently been involved in a project which had to
account for all the different ways you can modify Python's method
dispatch, that you just figure out the features of Python that you
need, and make sure they work.  Don't go exploring or you might lose a
week :-)  You might better spend your time learning a bit about Python
idioms; for example, in your code:

  print "Test 1: " + str(Test.i)

would be more simply (and efficiently) written as:

  print "Test 1:', Test.i

You might also look at PEP 8 for some hints on naming and so forth:

        <http://www.python.org/dev/peps/pep-0008/>

-- 
Nicholas Riley <[EMAIL PROTECTED]> | <http://www.uiuc.edu/ph/www/njriley>
_______________________________________________
users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to