Static methods of str instance in Python

So, I found out that strings have a center method.

>>> 'a'.center(3) ' a ' 

Then I noticed that I can do the same using the 'str' object, which is a type since

 >>> type(str) <type 'type'> 

Using this type object, I could access string methods such as static functions.

 >>> str.center('a',5) ' a ' 

Alas! This violates zen python.

There should be one - and only one desirable - an easy way to do this.

Even the types of the two methods are different.

 >>> type(str.center) <type 'method_descriptor'> >>> type('Ni!'.center) <type 'builtin_function_or_method'> 

Now,

  • Is this an example of how classes should be designed in python?
  • Why different types?
  • What is the descriptor method and why should I bother?

Thanks for answers!

+4
source share
5 answers

Just how classes work in Python:

 class C: def method(self, arg): print "In C.method, with", arg o = C() o.method(1) C.method(o, 1) # Prints: # In C.method, with 1 # In C.method, with 1 

When you say o.method(1) , you can think of it as a shorthand for C.method(o, 1) . A method_descriptor is part of the mechanism that makes it work.

+15
source

There should be one - and only one desirable - an easy way to do this.

Philosophically speaking, there is only one obvious way to do this: 'a'.center (3). The fact that there is a non-obvious way to call any method (i.e. well explained in comparison with previous commentators o.method (x) and Type.method (o, x)), which are useful in many contexts, fits perfectly with python zen .

Your homework is to read Guido Why Explicit I Must Stay .

+8
source

To extend the answer to the RichieHindle:

In Python, all methods in a class idiomatically accept the "self" parameter. For instance:

 def method(self, arg): pass 

This "self" argument tells Python which instance of the class is called by the method. When you call a method on an instance of a class, this is usually passed implicitly to you:

 o.method(1) 

However, you also have the option to use the Object class and explicitly pass an instance of the class:

 C.method(o, 1) 

To use your example string, str.center is the method for the str object:

 "hi".center(5) 

is equivalent to:

 str.center("hi", 5) 

You pass a hello to the str instance on the object, explicitly doing what is usually implicit.

+4
source
 'a'.center(3) == str.center('a',3) 

There is only one way to do this.

+2
source

The method descriptor is a normal class with the __get__ , __set__ and __del__ .

When, for example, __get__ , 2 or 3 arguments are passed:

  • self , which is the handle class itself,
  • inst , which is the object of the call to which the described method should be bound,
  • cls , which may be None .

To illustrate method_descriptor technology, let me give this example:

 class Descriptor(object): def __init__(self, m): self._meth=m def __get__(self, inst, cls=None): if cls is None: cls=type(inst) delattr(cls,self._meth.func_name) def _inst_meth(*a): return self._meth(inst,*a) return _inst_meth def instanceonlymethod(f): return Descriptor(f) class Test(object): def meth_1(self,*a): return '-'.join(str(i) for i in a) @instanceonlymethod def meth_2(self,*a): return '-'.join(str(i) for i in a) t=Test() print t.meth_1(2,3,4,5) #returns: 2-3-4-5 print Test.meth_1(t,1,2,3,4) #returns: 1-2-3-4 print t.meth_2(2,3,4,5) #returns: 2-3-4-5 try: print Test.meth_2(t,1,2,3,4) except Exception, why: #for 2.6, see changes print why #returns: type object 'Test' has no attribute 'meth_2' 

Now when you call Test.meth_2(t, 1,2,3,4) , it will not work.

+1
source

All Articles