Classes - converting external function to class's method.

Ivan Evstegneev webmailgroups at gmail.com
Sun Dec 14 11:20:48 EST 2014


Hello Everyone,

I have stuck a bit with this example(took this one from the book).

Here are a description steps of what I've done till now:
 

Step 1 - creating an empty namespace:

>>>class rec: pass

Step 2 - adding some attributes:

>>>rec.name = 'Bob' 
>>>rec.age = 40

Step 3 - Creating an instance:

>>>x= rec()

Step 4 - write down external function: 

>>>def uppername(obj):
	return obj.name.upper()

Step 5 - applying this function on x:

>>>uppername(x)
'BOB'

Till this moment its Ok.

But:

Step 6 - Creating a class method:


>>>rec.method = uppername

Then using the "help" function I  get (just checking what happened):

>>>help(rec)
class rec(builtins.object)
 |  Methods defined here:
 |  
 |  method = uppername(obj)
 |  
 |  ----------------------------------------------------------------------
 |omitted text......

 |------------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  age = 40
 |  
 |  name = 'Bob'


Then the same about x:

>>>help(x)
class rec(builtins.object)
 |  Methods defined here:
 |  
 |  method = uppername(obj)
 | -------------------------------------------------------------------
 omitted text .....
|---------------------------------------------------------------------


The last check I've made:

>>> help(x.method)
Help on method uppername in module __main__:

uppername() method of __main__.rec instance

>>> help(rec.method)
Help on function uppername in module __main__:

uppername(obj)

and now to the Step 7 - using this new "method" on x:

>>>x.method()
'BOB'

>>>rec.method()
.....
.....
TypeError: uppername() missing 1 required positional argument: 'obj'

and then:

>>>rec.method(rec)
'BOB'

So my the question is: what is going on here? How this actually works?

According to the book's downside note:
****************************************************************************
******
In fact, this is one of the reasons the self argument must always be
explicit in Python methods-because
methods can be created as simple functions independent of a class, they need
to make the implied instance
argument explicit. They can be called as either functions or methods, and
Python can neither guess nor
assume that a simple function might eventually become a class's method. The
main reason for the explicit
self argument, though, is to make the meanings of names more obvious: names
not referenced through
self are simple variables mapped to scopes, while names referenced through
self with attribute notation
are obviously instance attributes.
****************************************************************************
*****

Keeping it in mind, I wrote this code:

>>> class myclass:
	def __init__(self, value):
		self.name = value
	def myupper(self):
		return self.name.upper()

And then:

>>> b = myclass('bob')
>>>b.myupper()
'BOB'

I made an assumption that this is what happens(roughly speaking) when I
write this:

>>>rec.method = uppername

Am I right? (close enough maybe?)


On the other hand, when I checked further:

>>>dir(x.method)
[........, '__self__',.......]

but 
>>>dir(rec.method)
[.... list of method and  '__self__'  wasn't there.....]

I got a "bit" confused. 

Why  actually in instance "x"
>>>x.method() 
can auto-assign an "x" to uppername() function argument, but it doesn't work
in a class "rec" itself?

So  I need to write down an "obj" argument manually.
Why '__self__' exists only in instance "x"? (maybe because "rec", initially
was created as an empty class?)

How does a function "uppername()" looks like, when I apply it to "rec"
class, so it becomes  a class's method?

So in such a case, when instance "x" receives an "update" it reads the new
method as I described above(I mean the code of "myclass")?


Thanks a  lot in advance,

Ivan. 







More information about the Python-list mailing list