Python中str的静态方法与实例方法

8 投票
5 回答
2512 浏览
提问于 2025-04-15 13:08

我了解到,字符串有一个叫做中心的方法。

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

然后我发现,我可以用一个叫做'str'的对象来做同样的事情,因为这个'str'是一个类型。

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

通过这个'type'对象,我可以像调用静态函数一样使用字符串的方法。

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

可惜!这违反了Python的设计哲学。

应该有一种——最好只有一种——明显的方法来做到这一点。

甚至这两种方法的类型都不一样。

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

现在,

  1. 这是不是一个关于Python中类应该如何设计的例子?
  2. 为什么这些类型会不一样?
  3. 什么是method_descriptor,为什么我需要关心它?

谢谢大家的回答!

5 个回答

5

来详细讲讲RichieHindle的回答:

在Python中,类里的所有方法通常都会有一个叫“self”的参数。比如:

def method(self, arg): pass

这个“self”参数告诉Python,方法是在哪个类的实例上被调用的。当你在一个类的实例上调用方法时,这个参数通常会自动传递给你:

o.method(1)

不过,你也可以选择使用类对象,并明确地传入类的实例:

C.method(o, 1)

以你的字符串例子为例,str.center就是str对象上的一个方法:

"hi".center(5)

这其实等同于:

str.center("hi", 5)

你把str实例“hi”传给了这个对象,明确地做了通常情况下自动完成的事情。

9

应该有一种——而且最好只有一种——明显的方法来完成这件事。

从哲学的角度来看,确实只有一种明显的方法来做这件事:'a'.center(3)。虽然有其他不那么明显的方法来调用任何函数(比如前面评论者提到的 o.method(x) 和 Type.method(o, x)),这些方法在很多情况下都很有用,但这完全符合Python的哲学。

你的作业是去读Guido的《为什么显式的self必须保留》

19

这就是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 是实现这个功能的一个部分。

撰写回答