到目前为止我们已经看到了Python中的几种数据结构:字符串和序列。它们每个都支持几种方法,这也是方程的变体形式。
例如,list
中的一个方法是reverse()
。从名字上就可以看出来,这个方法可以颠倒这个序列(也就是说,第一项放在最后一项,最后一项放在第一项)。你需要使用一个(.)来使用此方法,结构如下:
«objectName».«methodName»(«list of arguments, if any»)
相比之下,我们已经见到的使用方程的句法是
«functionName»(«list of arguments, if any»)
下面这个例子是在序列上使用reverse 的方法。
这有一个方法的例子,它带有一个实参str. startswith:
多种方法
在下面,我们会提到最普遍的字符串和序列方法。这些方法大多都能通过你自己写的程序代替,但是使用标准的方法会让代码更便于阅读和编辑。
序列
这些方法不会更改序列:
list.index(X)
: 寻找序列中的X
。具体来说,这个方法返还i
,其中list[i]==X
通过搜索序列中所有的项返还最小的i
。如果X
在序列中不存在,会发生ValueError
。- 如果
X
是序列中的项,X in list
返还True
,否则False
。使用这个会避免ValueError
(in
是一个运算符,而不是一个方法)。
- 如果
list.count(X)
: 返还X
在序列中出现的次数
这些方法会改变序列:
list.append(X)
把X
加到list
末list.insert(i, X)
把X
加到位置i
上- list. extend (L)在结尾加上一个序列L
list.remove(X)
移除第一次出现的X
list.pop(i)
删除& 返还list[i]
,而list.pop()
删除& 返还最后一项del list[i]
删除序列list
中第i
项(注意,这是一个"del
statement",不是一个方法)list.reverse()
颠倒序列list.sort()
将序列排序
上述所有的方法除了pop
,都返还None
。其中一些带有些许不同实参的方程也可以被调用;详见Python中的序列方法。序列也支持复杂的子范围,名为"slices",允许整个子范围的插入和删除,类似于我们在previous 课中所看见的string[x:y:z]
。
字符串
就像序列一样,你可以对字符串使用in
,index
和count
。这些更加方便,因为他们也对子链适用,并不仅仅是找到单个的字符:
S in T
是一个布尔值,判断是否字符串S
是字符串T
的子链S.index(T)
找到S
中子链T
第一次出现的的第一个字母的索引S.count(T)
返还S
的子链T
不重叠出现的次数
下面是一些有用的str
方法:
- 字母:
capitalize, lower, upper, islower, isupper
- 字符:
isalpha, isdigit
- Padding:
center, ljust, rjust
;strip
会消除padding - 子链:
endswith, startswith, find, replace
- 分解:
split, splitlines
我们会在需要的时候更详细的介绍这些方法。完整详细的字符串方法列表会
在Python 文档中给出。
字符串是不可更改的。我们提到过list.reverse()
可以颠倒一个序列,但是没有str.reverse()
方法。这是因为字符串一旦被创建就不能被更改。在第17课中我们会做以解释。
这是一个字符串方法的例子:S.replace(old, new)
返还一个更改过的S
,所有的子链old
被更换成new
。这会创建一个新的字符串,而不是更改以前的字符串:
下面的这些方法对下一个练习会有所帮助:
str.replace
,我们刚介绍过- 布尔方法
str.isalpha()
,如果str
是一个只由字母组成的字符串(或字符),返还True
- 布尔方法
str.isdigit()
,如果str
是一个只由数字组成的字符串(或字符),返还True
str.upper()
返还str
的大写形式。
这节课剩余的部分有点技术性,余下的课程对这方面知识并没有要求。 |
更多对象
随着对Python 的深入学习,你会发现除了字符串和序列以外的更多的类型。其他一些你可能觉得有用的东西包括文件对象,集合,字典。它们都有很多有用的方法。你可以通过使用dir
方程列出Python中一个对象的所有的方法:
查看对象的性质被称作反省。Python中所有的东西都可以有方法:
一些dir
中的项实际上是member variables而不是方法,例如int.denominator
是一个数字,不是一个方程。严格来说,方程是Python中的对象,所以子方程是子变量中的特殊例子。
你也可以对模块进行反省。如果你先下令import math
,然后下令dir(math)
,按后你就会得到一序列math
模块中所有的东西, 包括数字pi
和方程sqrt
。
为什么要有对象?
为什么我们有类似于S.index(T)
的方法,而不是一个简单的方程index(S, T)
?换句话说,为什么我们有对象 S
和方法 str.index()
?
当你开始对更复杂的,不同种数据进行编程的时候,对象的主要优势会显现出来。每一种对象(比如,str、class)不仅代表可以被储存的数据(比如,一系列字符和长度),还代表可以在其上进行运算的类型(比如,转换为大写或产生子链)。一个更复杂的例子是文件对象:他们代表被打开的文件名字,你现在在文件中的位置,以及阅读,写的方法。你甚至可以定义你自己的数据类型!
这个通常的方法被称为"面向对象的编程" (OOP)。其中的一些好处是:
- 机构:
math
模块中的所有东西都可以通过math.«name»
句法得到,避免在程序中重复写已经存在的变量名字。 - 封装: 就像是一个能同时对几个字符串或几个文件进行处理的程序一样,你可以对很多由其他类别定义的不同的数据类型进行处理。
- 重复使用: 一旦你定义了一个数据类型(比如
str
)或一个方法库(比如math
),你可以重复使用它,或把它给其他人使用。 - 调试: 早些时候,我们看到了如何编写一些方程来预防拥有近似代码的副本,从而使调试更简单。编写一个位置对应一个数据的所有的方程(种类定义)可以起到相同的效果。
- 种类间的关系: Python知道
index
方法对于字符串来说是一个意思,对于序列来说是别的意思。同样的,Python不仅可以在你的电脑上读取并书写文档,也可以在网络上读取并书写数据。在这两个情况中(字符或序列顺序,本地或远程文件),相关的种类可以用同一种方式解决。那就是通过使用inheritance的概念。
在剩下的CS Circles课程中,我们只会使用对象和方法;你可以自行了解更多有关创建自己独有的种类的信息(查看资源网页)。
接下来的三节课可以按任何顺序完成,会有一系列结合之前课程主题的问题。