为什么有些方法使用点符号而其他方法不使用?

Why do some methods use dot notation and others don't?

所以,我才刚刚开始学习Python(使用Codecademy),有点迷茫。

为什么有些方法采用参数,而另一些方法使用点符号?

len() 接受一个参数,但不适用于点符号:

>>> len("Help")
4
>>>"help".len()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'len'

同样:

>>>"help".upper()
'HELP'
>>>upper("help")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'upper' is not defined

这里的关键词是方法。函数和方法之间存在细微差别。

方法

是在给定对象的class中定义的函数。例如:

class Dog:
    def bark(self):
        print 'Woof woof!'

rufus = Dog()
rufus.bark() # called from the object

函数

一个函数是一个全局定义的过程:

def bark():
    print 'Woof woof!'

至于你关于len函数的问题,全局定义的函数调用对象的__len__特殊方法。所以在这种场景下,就是一个可读性的问题。

否则,当方法只适用于某些对象时会更好。当函数应用于多个对象时会更好。例如,如何将数字大写?您不会将其定义为函数,而是将其定义为仅在字符串 class 中的方法。

您所说的 "dot notation" 是 class 方法,它们仅适用于具有 class 实现者定义的方法的 classes。 len 是一个内置函数,它接受一个参数和 returns 该对象的大小。如果 class 愿意,它可能会实现一个名为 len 的方法,但大多数情况下不会。内置 len 函数有一个规则,如果 class 有一个名为 __len__ 的方法,它将使用它,所以这个工作:

>>> class C(object):
...     def __len__(self):
...             return 100
... 
>>> len(C())
100

"help".upper则相反。字符串 class 定义了一个名为 upper 的方法,但这并不意味着还必须有一个名为 upper 的函数。原来在string模块中有一个upper函数,但是一般情况下你不需要因为实现了一个class方法就额外实现一个函数。

这是函数方法之间的区别。如果您只是学习基础知识,也许可以简单地接受这个区别是存在的,你最终会明白的。

还在吗?实际上,这甚至都不难。在面向对象的编程中,方法在很多方面都优于函数,因为这意味着一种类型的对象可以覆盖 版本的方法而不影响系统的其余部分。

例如,假设您有一种新的字符串,当您调用 .upper() 时,重音字符应该失去重音。这种类型的实例可以 subclass str 并且在其他方​​面的行为完全相同,基本上是免费的;他们需要重新定义的只是 upper 方法(即便如此,也可能调用基础 class 的方法,并且只在处理重音小写字符时更改逻辑)。预计在字符串上工作的软件将继续工作,如果你传入一个需要标准 str 的新类型的对象,甚至不知道有什么区别。

Python 中的一个设计原则是 一切都是对象。 这意味着您甚至可以为 object 这样的基本对象创建自己的替代品、classtype,即扩展或覆盖您的应用程序或平台的基本语言。

事实上,这发生在 Python 2 中,当时 unicode 字符串被引入语言。许多应用程序软件继续像以前一样工作,但现在有 unicode 个实例,而以前的代码是为处理 str 个实例而编写的。 (这种差异在 Python 3 中不再存在;或者更确切地说,称为 str 并且几乎无处不在的类型现在称为 bytes 并且仅在您特别想要处理时使用不是文本的数据。)

回到我们新的upper方法,想想相反的情况;如果 upper 只是标准库中的一个函数,你怎么会考虑修改需要 upper 以不同方式运行的软件?如果明天您的老板希望您为 lower 做同样的事情怎么办?这将是一项艰巨的任务,您必须对整个代码库进行的更改很容易导致意大利面条式结构,并且可能会引入细微的新错误。

这是面向对象编程的基石之一,但当您在更结构化的介绍中学习其他两三个原则时,它可能只有 真正 有意义。现在,也许快速而粗略的总结是 "methods make the implementation modular and extensible."