所以,我已经知道字符串有一个中心方法。
>>> 'a'.center(3)
' a '
然后我注意到我可以使用'str'对象做同样的事情,因为
>>> type(str)
<type 'type'>
使用这个'type'对象,我可以访问字符串方法,就像它们是静态函数一样。
>>> str.center('a',5)
' a '
唉!这违反了蟒蛇的禅宗。
应该有一个 - 最好只有一个 - 显而易见的方法。
即使这两种方法的类型也不同。
>>> type(str.center)
<type 'method_descriptor'>
>>> type('Ni!'.center)
<type 'builtin_function_or_method'>
现在,
感谢您的回答!
答案 0 :(得分:17)
这就是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
当您说o.method(1)
时,您可以将其视为C.method(o, 1)
的简写。 method_descriptor
是使这项工作成功的机制的一部分。
答案 1 :(得分:9)
应该有一个 - 最好只有一个 - 显而易见的方法。
从哲学上讲, 只有一种显而易见的方法:'a'.center(3)。事实上有一种不明显的方式来调用任何方法(即前面的注释器o.method(x)和Type.method(o,x)),这在许多情况下很有用,这一点非常符合与蟒蛇的禅宗。
你的家庭作业是阅读Guido的Why the Explicit Self Has to Stay。
答案 2 :(得分:5)
扩展RichieHindle的答案:
在Python中,类上的所有方法都是惯用的“self”参数。例如:
def method(self, arg): pass
“self”参数告诉Python调用该方法的类的实例。当您在类实例上调用方法时,通常会为您隐式传递:
o.method(1)
但是,您还可以选择使用Object类,并显式传入类实例:
C.method(o, 1)
要使用你的字符串示例,str.center是str对象上的一个方法:
"hi".center(5)
相当于:
str.center("hi", 5)
您正在将str实例“hi”传递给对象,显式执行通常隐含的操作。
答案 3 :(得分:2)
'a'.center(3) == str.center('a',3)
只有一种方法可以做到。
答案 4 :(得分:1)
方法描述符是具有__get__
,__set__
和__del__
方法的普通类。
例如,当调用__get__
时,会传递2或3个参数:
self
,这是描述符类本身,inst
,这是应该绑定“描述”方法的调用者对象,cls
,可以是None
。为了说明method_descriptor机器,让我举个例子:
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'
现在,当您致电Test.meth_2(t, 1,2,3,4)
时,它将无效。