本文以 Eric Matthes 的《Python编程:从入门到实践》为基础,以有必定其余语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章。python
读完本篇文章后,可对 Python 语言特性、编码风格有必定了解,并可写出简单的 Python 程序。程序员
各个系统的 Python 安装教程请自行查阅资料,这里再也不赘述。编程
检查 Python 版本,在命令行输入 python
便可,同时会进入命令行交互模式,能够在这里执行 python 命令。json
若是电脑中安装了 python2.x 和 python3.x 两个版本,输入 python
运行的是 2.x 版本。想运行 3.x,则需输入 python3
。python3.x
在命令行输入 python
:数据结构
Solo-mac:~ solo$ python Python 2.7.10 (default, Aug 17 2018, 19:45:58) [GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.0.42)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
在命令行输入 python3
:app
Solo-mac:~ solo$ python3 Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
输入 exit()
便可退出命令行模式。python2.7
若是是写好了一个 python 文件,想经过命令行运行它,进入这个目录,在命令行输入 python 文件名.py
便可。编程语言
好比桌面上有个文件 hello.py
,内容是打印一句话:ide
print("Hello, Python")
想运行它,先进入 Desktop 目录,再在命令行输入 python hello.py
就能运行:
Solo-mac:Desktop solo$ python hello.py Hello, Python
变量名应该是小写的,虽然没有强制规定,可是约定俗称的规则。
字符串就是一系列字符。在Python中,用引号括起的都是字符串,其中的引号能够是单引号,也能够是双引号,还能够同时使用。如:
"This is a string." 'This is also a string.' "I love 'python'"
下面介绍字符串的简单运算。
title()以首字母大写的方式显示每一个单词,即将每一个单词的首字母都改成大写。
>>> name = 'solo coder' >>> name.title() 'Solo Coder'
将字符串改成所有大写或所有小写。
>>> name 'solo coder' >>> name.upper() 'SOLO CODER' >>> name.lower() 'solo coder' >>> name 'solo coder'
注意:title()、upper()、lower() 均不改变原字符串,只是输出了一个新的字符串。
Python使用加号(+)来合并字符串。
>>> first = 'solo' >>> last = 'coder' >>> full = first + ' ' + last >>> full 'solo coder'
在编程中,空白泛指任何非打印字符,如空格、制表符和换行符。
要在字符串中添加制表符,可以使用字符组合 \t
,要在字符串中添加换行符,可以使用字符组合 \n
。
>>> print('\tPython') Python >>> print('Hello,\nPython') Hello, Python
rstrip()
删除右侧空白,lstrip()
删除左侧空白,strip()
删除两端空白。
>>> msg = ' Python ' >>> msg ' Python ' >>> msg.rstrip() ' Python' >>> msg.lstrip() 'Python ' >>> msg.strip() 'Python' >>> msg ' Python '
注意执行完去空格命令后,再打印出 msg,仍是原来的字符串,这说明 strip()
也不改变原来的字符串。
在Python 2中,print语句的语法稍有不一样:
>>> python2.7 >>> print "Hello Python 2.7 world!" Hello Python 2.7 world!
在Python 2中,无需将要打印的内容放在括号内。从技术上说,Python 3中的print是一个函数,所以括号必不可少。有些Python 2 print语句也包含括号,但其行为与Python 3中稍有不一样。简单地说,在Python 2代码中,有些print语句包含括号,有些不包含。
在Python中,可对整数执行加(+)减(-)乘(*)除(/)运算。
>>> 2 + 3 5 >>> 3 - 2 1 >>> 2 * 3 6 >>> 3 / 2 1.5
Python还支持运算次序,所以你可在同一个表达式中使用多种运算。你还可使用括号来修 改运算次序,让Python按你指定的次序执行运算,以下所示:
>>> 2 + 3*4 14 >>> (2 + 3) * 4 20
Python将带小数点的数字都称为浮点数。大多数编程语言都使用了这个术语,它指出了这样一个事实:小数点可出如今数字的任何位置。
从很大程度上说,使用浮点数时都无需考虑其行为。你只需输入要使用的数字,Python一般都会按你指望的方式处理它们:
>>> 0.1 + 0.1 0.2 >>> 0.2 + 0.2 9 0.4 >>>2 * 0.1 0.2 >>>2 * 0.2 0.4
但须要注意的是,结果包含的小数位数多是不肯定的:
>>> 0.2 + 0.1 0.30000000000000004 >>> 3 * 0.1 0.30000000000000004
全部语言都存在这种问题,没有什么可担忧的。Python会尽力找到一种方式,以尽量精确地表示结果,但鉴于计算机内部表示数字的方式,这在有些状况下很难。后面将会学习更多的处理方式。
若是用数字跟字符串拼接,就会出现类型错误。为避免这个问题,可使用 str()
将数字转换为字符串再进行操做。
>>> age = 18 >>> print('my age is ' + age) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate str (not "int") to str >>> print('my age is ' + str(age)) my age is 18
在Python 2中,将两个整数相除获得的结果稍有不一样:
>>> python2.7 >>> 3 / 2 1
Python返回的结果为1,而不是1.5。在Python 2中,整数除法的结果只包含整数部分,小数部 分被删除。请注意,计算整数结果时,采起的方式不是四舍五入,而是将小数部分直接删除。
在Python 2中,若要避免这种状况,务必确保至少有一个操做数为浮点数,这样结果也将为 浮点数:
>>> 3 / 2 1 >>> 3.0 / 2 1.5 >>> 3 / 2.0 1.5 >>> 3.0 / 2.0 1.5
从Python 3转而用Python 2或从Python 2转而用Python 3时,这种除法行为经常会使人迷惑。使用或编写同时使用浮点数和整数的代码时,必定要注意这种异常行为。
在Python中,注释用井号(#)标识。井号后面的内容都会被Python解释器忽略。如
# 向你们问好 print("Hello Python people!")
列表由一系列按特定顺序排列的元素组成。
在Python中,用方括号([])来表示列表,并用逗号来分隔其中的元素。
>>> list = [] >>> list.append('haha') >>> list.append('heihei') >>> list.append('hehe') >>> list ['haha', 'heihei', 'hehe'] >>> list[0] 'haha'
获取最后一个元素能够用 -1,如 list[-1] 是获取最后一个元素,list[-2] 是获取倒数第二个元素。
修改元素直接用索引修改
>>> list[0] = 'nihao' >>> list ['nihao', 'heihei', 'hehe']
能够在末尾添加,也能够在任意位置插入。
在末尾添加:append
>>> list.append('wa') >>> list ['nihao', 'heihei', 'hehe', 'wa']
插入:insert
>>> list.insert(1, 'hello') >>> list ['nihao', 'hello', 'heihei', 'hehe', 'wa']
删除有三种方式:
>>> list ['nihao', 'hello', 'heihei', 'hehe', 'wa'] >>> del list[1] >>> list ['nihao', 'heihei', 'hehe', 'wa'] >>> list.pop() 'wa' >>> list.remove('hehe') >>> list ['nihao', 'heihei']
给 pop()
传索引删除其余位置的值
>>> list ['nihao', 'heihei'] >>> list.pop(0) 'nihao' >>> list ['heihei']
注意:
方法remove()只删除第一个指定的值。若是要删除的值可能在列表中出现屡次,就须要使用循环来判断是否删除了全部这样的值。
若是你不肯定该使用del语句仍是pop()方法,下面是一个简单的判断标准:若是你要从列表中删除一个元素,且再也不以任何方式使用它,就使用del语句;若是你要在删除元素后还能继续使用它,就使用方法pop()。
本节将介绍列表的排序、反转、计算长度等操做。
列表的排序主要有两种方式:
使用 sort()
方法将改变原列表。若是要反转排序,只需向sort()方法传递参数 reverse=True。
>>> list ['zhangsan', 'lisi', 'bob', 'alex'] >>> list.sort() >>> list ['alex', 'bob', 'lisi', 'zhangsan'] >>> list.sort(reverse=True) >>> list ['zhangsan', 'lisi', 'bob', 'alex']
函数 sorted()
让你可以按特定顺序显示列表元素,同时不影响它们在列表中的原始排列顺序。
若是要反转排序,只需向 sorted()
传递参数 reverse=True。
>>> list = ['douglas','alex','solo','super'] >>> sorted(list) ['alex', 'douglas', 'solo', 'super'] >>> list ['douglas', 'alex', 'solo', 'super'] >>> sorted(list, reverse=True) ['super', 'solo', 'douglas', 'alex'] >>> list ['douglas', 'alex', 'solo', 'super']
要反转列表元素的排列顺序,可以使用方法 reverse()
。 reverse()
也会改变原始列表。
reverse()
只会按原来的顺序反转,不会进行额外的按字母排序。
>>> list ['douglas', 'alex', 'solo', 'super'] >>> list.reverse() >>> list ['super', 'solo', 'alex', 'douglas']
使用函数len()可快速获悉列表的长度。
>>> list ['super', 'solo', 'alex', 'douglas'] >>> len(list) 4
使用 for…in
循环。
python 以缩进来区分代码块,因此须要正确的缩进
>>> cats ['super', 'solo', 'alex', 'douglas'] >>> for cat in cats: ... print(cat) ... super solo alex douglas
Python函数range()让你可以轻松地生成一系列的数字。
>>> for value in range(1,5): ... print(value) ... 1 2 3 4
注意:range() 会产生包含第一个参数但不包含第二个参数的一系列数值。
使用 range()
建立列表
>>> numbers = list(range(1,6)) >>> numbers [1, 2, 3, 4, 5]
range()
还能够指定步长。下面的例子生成了从0开始,到11的偶数:
>>> nums = list(range(0,11,2)) >>> nums [0, 2, 4, 6, 8, 10]
有几个专门用于处理数字列表的Python函数。
>>> numbers [1, 2, 3, 4, 5] >>> min(numbers) 1 >>> max(numbers) 5 >>> sum(numbers) 15
列表解析将for循环和建立新元素的代码合并成一行,并自动附加新元素。
>>> squares = [value**2 for value in range(1,11)] >>> squares [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
要使用这种语法,首先指定一个描述性的列表名,如squares;而后,指定一个左方括号, 并定义一个表达式,用于生成你要存储到列表中的值。在这个示例中,表达式为 value ** 2,它计 算平方值。接下来,编写一个for循环,用于给表达式提供值,再加上右方括号。在这个示例中, for循环为for value in range(1,11),它将值1~10提供给表达式 value ** 2。请注意,这里的for 语句末尾没有冒号。
要建立切片,可指定要使用的第一个元素和最后一个元素的索引。与函数range()同样,Python在到达你指定的第二个索引前面的元素后中止。要输出列表中的前三个元素,须要指定索引0~3,这将输出分别为0、1和2的元素。
>>> names = ['aa','bb','cc','dd'] >>> print(names[1:4]) ['bb', 'cc', 'dd']
若是你没有指定第一个索引,Python将自动从列表开头开始:
>>> print(names[:4]) ['aa', 'bb', 'cc', 'dd']
若是没有指定终止索引,将自动取到列表末尾
>>> print(names[2:]) ['cc', 'dd']
也可使用负数索引,好比返回最后三个元素
>>> print(names[-3:]) ['bb', 'cc', 'dd']
遍历切片
>>> for name in names[1:3]: ... print(name) ... bb cc
可使用切片来快速复制列表,不指定开始索引和结束索引。
>>> names ['aa', 'bb', 'cc', 'dd'] >>> names2 = names[:] >>> names2 ['aa', 'bb', 'cc', 'dd']
用切片复制出来的新列表,跟原来的列表是彻底不一样的列表,改变其实一个不会影响另外一个列表。
>>> names.append('ee') >>> names ['aa', 'bb', 'cc', 'dd', 'ee'] >>> names2 ['aa', 'bb', 'cc', 'dd']
而若是简单的经过赋值将 names 赋值给 names2,就不能获得两个列表,实际上它们都指向了同一个列表。若是改变其中一个,另外一个也将被改变。
>>> names ['aa', 'bb', 'cc', 'dd'] >>> names2 = names >>> names2 ['aa', 'bb', 'cc', 'dd'] >>> names.append('ee') >>> names ['aa', 'bb', 'cc', 'dd', 'ee'] >>> names2 ['aa', 'bb', 'cc', 'dd', 'ee']
Python将不能修改的值称为不可变的,而不可变的列表被称为元组。
元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可使用索引来访问其元素,就像访问列表元素同样。
>>> food = ('apple', 'orange') >>> food[0] 'apple' >>> food[1] 'orange' >>> food[1] = 'banana' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
遍历用法跟列表一致。
每条if语句的核心都是一个值为True或False的表达式,这种表达式被称为条件测试。
检查是否相等,用 ==
检查是否不相等,用 !=
数字比较 >
、 <
、 >=
、 <=
多个条件与 and
多个条件或 or
判断列表是否包含某元素 in
>>> names ['aa', 'bb', 'cc', 'dd', 'ee'] >>> 'bb' in names True
判断列表是否不包含某元素
>>> names ['aa', 'bb', 'cc', 'dd', 'ee'] >>> 'ff' not in names True
简单的 if-else
>>> a = 10 >>> if a > 10: ... print('hello') ... else: ... print('bye') ... bye
if-elif-else
>>> if a<5: ... print(a<5) ... elif 5<a<10: ... print('5<a<10') ... else: ... print('a>10') ... a>10
在Python中,字典是一系列键-值对。每一个键都与一个值相关联,你可使用键来访问与之相关联的值。与键相关联的值能够是数字、字符串、列表乃至字典。事实上,可将任何Python对象用做字典中的值。
在Python中,字典用放在花括号{}中的一系列键-值对表示。
>>> user = {'name':'bob', 'sex':'male', 'age':20} >>> user {'name': 'bob', 'sex': 'male', 'age': 20}
要获取与键相关联的值,可依次指定字典名和放在方括号内的键。
>>> user {'name': 'bob', 'sex': 'male', 'age': 20} >>> user['name'] 'bob' >>> user['age'] 20
字典是一种动态结构,可随时在其中添加键—值对。
>>> user['city']='beijing' >>> user {'name': 'bob', 'sex': 'male', 'age': 20, 'city': 'beijing'}
要修改字典中的值,可依次指定字典名、用方括号括起的键以及与该键相关联的新值。
>>> cat = {} >>> cat['color'] = 'white' >>> cat['age'] = 4 >>> cat {'color': 'white', 'age': 4} >>> cat['age'] = 6 >>> cat {'color': 'white', 'age': 6}
对于字典中再也不须要的信息,可以使用del语句将相应的键—值对完全删除。使用del语句时,必须指定字典名和要删除的键。
>>> del cat['color'] >>> cat {'age': 6}
字典可用于以各类方式存储信息,所以有多种遍历字典的方式:可遍历字典的全部键—值对、键或值。
items()
>>> cat {'age': 6, 'color': 'white', 'city': 'beijing'} >>> for k,v in cat.items(): ... print(k + '-' + str(v)) ... age-6 color-white city-beijing
经过 for k,v in cat.items()
的方式遍历全部的键值对,k
表明键,v
表明值。
注意:即使遍历字典时,键—值对的返回顺序也与存储顺序不一样。Python不关心键—值对的存储顺序,而只跟踪键和值之间的关联关系。
keys()
若是不须要用值,能够用 keys()
遍历出全部的键。
>>> cat {'age': 6, 'color': 'white', 'city': 'beijing'} >>> for k in cat.keys(): ... print(k.title()) ... Age Color City
上面的例子打印出了 cat
的全部键,用字符串的 title()
方法使每一个单词的首字母大写。
遍历字典时会默认遍历全部的键,for k in cat.keys()
和 for k in cat
的效果同样。
按顺序遍历全部键,可用 sorted()
排序,这让Python列出字典中的全部键,并在遍历前对这个列表进行排序。
>>> for k in sorted(cat.keys()): ... print(k.title()) ... Age City Color
values()
>>> for value in cat.values(): ... print(str(value)) ... 6 white beijing
若是须要剔除重复项,可使用 set()
>>> cat {'age': 6, 'color': 'white', 'city': 'beijing', 'city2': 'beijing'} >>> for value in cat.values(): ... print(str(value)) ... 6 white beijing beijing >>> for value in set(cat.values()): ... print(str(value)) ... beijing white 6
能够在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。这里就不演示了。
函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便你使用。
>>> msg = input('Please input your name: ') Please input your name: solo >>> msg 'solo'
若是你使用的是Python 2.7,应使用函数raw_input()来提示用户输入。这个函数与Python 3中的input()同样,也将输入解读为字符串。
Python 2.7也包含函数input(),但它将用户输入解读为Python代码,并尝试运行它们。若是你使用的是Python 2.7,请使用raw_input()而不是input()来获取输入。
若是想将输入的内容转换为数字,能够用 int()
来转换。
for循环用于针对集合中的每一个元素都一个代码块,而while循环不断地运行,直到指定的条件不知足为止。
>>> num = 1 >>> while num <= 5: ... print(str(num)) ... num += 1 ... 1 2 3 4 5
要当即退出while循环,再也不运行循环中余下的代码,也无论条件测试的结果如何,可以使用break语句。break语句用于控制程序流程,可以使用它来控制哪些代码行将执行,哪些代码行不执行,从而让程序按你的要求执行你要执行的代码。
要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可以使用continue语句,它不像 break 语句那样再也不执行余下的代码并退出整个循环。
Python 用关键字 def
来定义函数,函数名以冒号 :
结尾,冒号以后的缩进里的内容都是函数体。
>>> def greet(): ... print('Hello World!') ... >>> greet() Hello World!
能够向函数传递参数。下面的例子向函数 greet()
传递了个参数 name
。其中 name
是形参,solo
是实参。
>>> def greet(name): ... print('Hello,' + name) ... >>> greet('solo') Hello,solo
向函数传递实参的方式不少,可以使用位置实参,这要求实参的顺序与形参的顺序相同;也可以使用关键字实参,其 中每一个实参都由变量名和值组成;还可以使用列表和字典。
你调用函数时,Python必须将函数调用中的每一个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。
>>> def student(name, age): ... print('Hello, My name is ' + name + ', I am ' + str(age) + ' years old') ... >>> student('solo', 18) Hello, My name is solo, I am 18 years old
按照形参定义的顺序传递的实参就称为位置实参。
关键字实参是传递给函数的名称—值对。关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
>>> student(age=18, name='solo') Hello, My name is solo, I am 18 years old
接着位置实参中的例子,student(name, age)
方法第一个参数是 name
,第二个参数是 age
。咱们用关键字实参指明传递的是哪个,即便顺序写乱了获得的结果也不会乱。
编写函数时,可给每一个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参值;不然,将使用形参的默认值。所以,给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。
>>> def student(name, age=18): ... print('Hello, My name is ' + name + ', I am ' + str(age) + ' years old') ... >>> student('bob') Hello, My name is bob, I am 18 years old >>> student('nicole') Hello, My name is nicole, I am 18 years old >>> student('bob', 20) Hello, My name is bob, I am 20 years old
如上,给 student()
函数定义的第二个参数 age
设置了默认值 18
,若是调用时只传一个参数,不管传的是什么 age
都是 18。当传两个参数时,传递的实参就会覆盖掉默认值。
注意:使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。这让Python依然可以正确地解读位置实参。
函数并不是老是直接显示输出,相反,它能够处理一些数据,并返回一个或一组值。函数返回 的值被称为返回值。在函数中,可以使用return语句将值返回到调用函数的代码行。返回值让你可以将程序的大部分繁重工做移到函数中去完成,从而简化主程序。
>>> def student(name): ... return name ... >>> name = student('solo') >>> name 'solo'
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。例如,下面的函数接受姓名和年龄,并返回一个表示人的字典:
>>> def build_person(name,age): ... person = {'name':name, 'age':age} ... return person ... >>> p = build_person('solo',18) >>> p {'name': 'solo', 'age': 18}
有时候,你预先不知道函数须要接受多少个实参,好在Python容许函数从调用语句中收集任意数量的实参。
>>> def person(*args): ... print(args) ... >>> person('name','age','address') ('name', 'age', 'address')
上面定义了一个函数 person()
,只有一个形参 *args
。形参名 *args
中的星号让 Python 建立一个名为 args
的空元组,并将收到的全部值都封装到这个元组中。
若是要让函数接受不一样类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python 先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
>>> def person(city, *args): ... print('city: ' + city + ', other args:') ... for value in args: ... print(value) ... >>> person('beijing', 'name', 'age', 'tel') city: beijing, other args: name age tel
函数 person()
有两个形参,第一个 city
是普通的位置实参,第二个 *args
是可变参数。
有时候,须要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种状况下,可将函数编写成可以接受任意数量的键—值对——调用语句提供了多少就接受多少。一个这样的示例是建立用户简介:你知道你将收到有关用户的信息,但不肯定会是什么样的信息。
def build_profile(first, last, **user_info): profile = {} profile['first_name'] = first profile['last_name'] = last for key,value in user_info.items(): profile[key] = value return profile user = build_profile('steven', 'bob', city='beijing', age=18) print(user)
执行代码,输出结果是:
{'first_name': 'steven', 'last_name': 'bob', 'city': 'beijing', 'age': 18}
能够将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。import语句容许在当前运行的程序文件中使用模块中的代码。
模块是扩展名为.py的文件,包含要导入到程序中的代码。
def eat(food): print('I am cat, I eat ' + food)
import cat cat.eat('fish')
控制台输出
I am cat, I eat fish
你还能够导入模块中的特定函数,这种导入方法的语法以下:
from module_name import function_name
经过用逗号分隔函数名,可根据须要从模块中导入任意数量的函数:
from module_name import function_0, function_1, function_2
上面的例子只导入 cat.py
中的 eat()
方法
from cat import eat eat('fish')
获得相同的结果。
若是要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名——函数的另外一个名称,相似于外号。要给函数指定这种特殊外号,须要在导入它时这样作。
from cat import eat as cat_eat cat_eat('fish')
将 cat.py
中的 eat()
方法导入并指定了别名 cat_eat
,使用时能够直接用别名使用。
你还能够给模块指定别名。经过给模块指定简短的别名,让你 可以更轻松地调用模块中的函数。
通用语法:import module_name as mn
import cat as c c.eat('fish')
使用星号(*)运算符可以让Python导入模块中的全部函数:
def eat(food): print('I am cat, I eat ' + food) def run(): print('cat run')
from cat import * eat('fish') run()
输出结果
I am cat, I eat fish cat run
因为导入 了每一个函数,可经过名称来调用每一个函数,而无需使用句点表示法。然而,使用并不是本身编写的 大型模块时,最好不要采用这种导入方法:若是模块中有函数的名称与你的项目中使用的名称相 同,可能致使意想不到的结果: Python 可能遇到多个名称相同的函数或变量,进而覆盖函数,而 不是分别导入全部的函数。
最佳的作法是,要么只导入你须要使用的函数,要么导入整个模块并使用句点表示法。这能 让代码更清晰,更容易阅读和理解。
应给函数指定描述性名称
函数名应只包含小写字母和下划线
每一个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式。
给形参指定默认值时,等号两边不要有空格:
def function_name(parameter_0, parameter_1='default value')
对于函数调用中的关键字实参,也应遵循这种约定:
function_name(value_0, parameter_1='value')
若是程序或模块包含多个函数,可以使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。
全部的import语句都应放在文件开头,惟一例外的情形是,在文件开头使用了注释来描述整个程序。
class Cat(): def __init__(self, name, color): self.name = name self.color = color def eat(self): print('cat ' + self.name + ' color ' + self.color + ', now eat') def run(self): print('cat ' + self.name + ' color ' + self.color + ', now run') my_cat = Cat('Spring', 'white') print(my_cat.name) print(my_cat.color) my_cat.eat() my_cat.run()
上面建立了类 Cat
,并实例化了 my_cat
,而后调用了类的方法 eat()
和 run()
。输出结果:
Spring white cat Spring color white, now eat cat Spring color white, now run
类中的函数称为方法。__init__()
是函数的构造方法,每档建立新实例时 Python 都会自动运行它。注意构造方法名字必须是这个,是规定好的。
上面的例子中__init__(self, name, color)
有三个形参,第一个形参 self
必不可少,还必须位于其余形参的前面。其余的形参能够根据须要调整。self
是一个指向实例自己的引用,让实例可以访问类中的属性和方法。
还能够经过实例直接访问属性:my_cat.name
。但在其余语言中并不建议这样作。
在Python 2.7中建立类时,须要作细微的修改——在括号内包含单词object:
class ClassName(object):
类中的每一个属性都必须有初始值,哪怕这个值是0或空字符串。在有些状况下,如设置默认值时,在方法__init__()
内指定这种初始值是可行的;若是你对某个属性这样作了,就无需包含为它提供初始值的形参。
从新定义 Cat
,在构造方法中给属性 age
设置默认值。
class Cat(): def __init__(self, name, color): self.name = name self.color = color self.age = 3 def eat(self): print('cat ' + self.name + ' color ' + self.color + ', now eat') def run(self): print('cat ' + self.name + ' color ' + self.color + ', now run') def print_age(self): print('cat`s age is ' + str(self.age))
能够以三种不一样的方式修改属性的值:直接经过实例进行修改,经过方法进行设置。
要修改属性的值,最简单的方式是经过实例直接访问它。
class Cat(): def __init__(self, name, color): self.name = name self.color = color self.age = 3 def eat(self): print('cat ' + self.name + ' color ' + self.color + ', now eat') def run(self): print('cat ' + self.name + ' color ' + self.color + ', now run') def print_age(self): print('cat`s age is ' + str(self.age)) my_cat = Cat('Spring', 'white') my_cat.print_age() my_cat.age = 4 my_cat.print_age()
输出结果为
cat`s age is 3 cat`s age is 4 复制代码
上例直接经过 my_cat.age = 4
修改了 age
属性的值。
再来更新代码,加入 update_age()
方法来修改 age
的属性。
class Cat(): def __init__(self, name, color): self.name = name self.color = color self.age = 3 def eat(self): print('cat ' + self.name + ' color ' + self.color + ', now eat') def run(self): print('cat ' + self.name + ' color ' + self.color + ', now run') def print_age(self): print('cat`s age is ' + str(self.age)) def update_age(self, age): self.age = age my_cat = Cat('Spring', 'white') my_cat.print_age() my_cat.update_age(10) my_cat.print_age()
运行代码输出:
cat`s age is 3 cat`s age is 10
一个类继承另外一个类时,它将自动得到另外一个类的全部属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的全部属性和方法,同时还能够定义本身的属性和方法。
class Animal(): def __init__(self, name, age): self.name = name self.age = age def run(self): print('Animal ' + self.name + ' run') class Cat(Animal): def __init__(self, name, age): super().__init__(name, age) cat = Cat('Tony', 2) cat.run()
运行程序,输出:
Animal Tony run
先定义了类 Animal
,又定义了 Cat
继承自 Animal
。 Animal
称为父类, Cat
称为子类。经过输出能够验证,子类继承了父类的方法。
在子类的构造方法中要先实现父类的构造方法:super().__init__(name, age)
。
还能够给子类定义本身的方法,或者重写父类的方法。
class Animal(): def __init__(self, name, age): self.name = name self.age = age def run(self): print('Animal ' + self.name + ' run') class Cat(Animal): def __init__(self, name, age): super().__init__(name, age) def play(self): print('Cat ' + self.name + ' play') def run(self): print('Cat ' + self.name + ' run') cat = Cat('Tony', 2) cat.run() cat.play()
咱们来修改下程序,Animal
类不变,Cat
类仍是继承了 Animal
,但定义了本身的方法 play()
并重写了父类方法 run()
。运行程序,获得输出:
Cat Tony run Cat Tony play
在Python 2.7中,继承语法稍有不一样,ElectricCar类的定义相似于下面这样:
class Car(object): def __init__(self, make, model, year): --snip-- class ElectricCar(Car): def __init__(self, make, model, year): super(ElectricCar, self).__init__(make, model, year) --snip--
函数super()须要两个实参:子类名和对象self。为帮助Python将父类和子类关联起来,这些实参必不可少。另外,在Python 2.7中使用继承时,务必在定义父类时在括号内指定object。
当一个文件过长时,能够将其中一部分代码抽离出去,而后导入到主文件中。
导入方式有多种:
导入单个类
假如 car.py
里定义了类 Car
from car import Car
从一个模块中导入多个类
假如 car.py
包含了三个类 Car
, Battery
和 ElectricCar
。
只导入一个类:
from car import ElectricCar
导入多个类,中间用逗号隔开:
from car import Car, ElectricCar
导入整个模块
还能够导入整个模块,再使用句点表示法访问须要的类。这种导入方法很简单,代码也易于阅读。因为建立类实例的代码都包含模块名,所以不会与当前文件使用的任何名称发生冲突。
import car my_car = car.Car()
导入模块中的全部类
要导入模块中的每一个类,可以使用下面的语法:
from module_name import *
不推荐使用这种导入方式,其缘由有二。
首先,若是只要看一下文件开头的import语句,就 能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出你使用了模块中 的哪些类。这种导入方式还可能引起名称方面的困惑。若是你不当心导入了一个与程序文件中其 他东西同名的类,将引起难以诊断的错误。这里之因此介绍这种导入方式,是由于虽然不推荐使 用这种方式,但你可能会在别人编写的代码中见到它。
须要从一个模块中导入不少类时,最好导入整个模块,并使用module_name.class_name语法 来访问类。这样作时,虽然文件开头并无列出用到的全部类,但你清楚地知道在程序的哪些地 方使用了导入的模块;你还避免了导入模块中的每一个类可能引起的名称冲突。
要使用文本文件中的信息,首先须要将信息读取到内存中。为此,你能够一次性读取文件的所有内容,也能够以每次一行的方式逐步读取。
with open('test.txt') as file_obj: contents = file_obj.read() print(contents)
open()
用于打开一个文件,参数为文件的路径。
关键字 with
在再也不须要访问文件后将其关闭。有了 with
你只管打开文件,并在须要时使用它,Python自会 在合适的时候自动将其关闭。
相比于原始文件,该输出惟一不一样的地方是末尾多了一个空行。为什么会多出这个空行呢?由于 read()
到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除多出来的空行,可在print语句中使用 rstrip()
。
文件路径能够是相对路径,也能够是绝对路径。
with open('test.txt') as file_obj: for line in file_obj: print(line.rstrip())
要以每次一行的方式检查文件,可对文件对象使用for循环。
with open('test.txt', 'w') as file_obj: file_obj.write("I love python")
在这个示例中,调用open()时提供了两个实参,第一个实参也是要打开的文件的名称;第二个实参(‘w’)告诉Python,咱们要以写入模式打开这个文件。
可选模式:
r
:只读。w
: 只写。若是文件不存在则建立,若是文件存在则先清空,再写入。a
:附加模式,写入的内容追加到原始文件后面。若是文件不存在则建立。r+
:可读可写。若是你省略了模式实参,Python将以默认的只读模式打开文件。
异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操做,同时告诉Python发生异常时怎么办。
try: print(5/0) except ZeroDivisionError: print("You can't divide by zero!")
try: print(5/0) except ZeroDivisionError: print("You can't divide by zero!") else: print("no exception")
若是 try
中的代码运行成功,没有出现异常,则执行 else
代码块中的代码。
Python 中使用 json.dump()
和 json.load()
来存储和读取 json 文件。
import json userInfo = {'username': 'jack', 'age': 18} with open('test.txt', 'w') as obj: json.dump(userInfo, obj) with open('test.txt') as obj: content = json.load(obj) print(content)
上例中用 json.dump()
把数据存入到了 test.txt
中,又用 json.load()
把数据从文件中取出并打印。
注意使用前先导入 json 模块。叉车出租
先定义一个拼接名字的函数 name_function.py
def get_formatted_name(first, last): full_name = first + ' ' + last return full_name.title()
再写测试类来测试这个函数
import unittest from name_function import get_formatted_name class NamesTestCase(unittest.TestCase): def test_name_function(self): full_name = get_formatted_name('david', 'alex') self.assertEqual(full_name, 'David Alex') unittest.main()
测试类要继承 unittest.TestCase
,经过 self.assertEqual
断言是否获得的结果和预期相等。
方法 | 用途 |
---|---|
assertEqual(a, b) | 核实a == b |
assertNotEqual(a, b) | 核实a != b |
assertTrue(x) | 核实x为True |
assertFalse(x) | 核实x为False |
assertIn(item, list) | 核实item在list中 |
assertNotIn(item, list) | 核实item不在list中 |
setUp()
方法若是你在TestCase类中包含了方法 setUp()
,Python将先运行它,再运行各个以test_打头的方法。
一般用于作一些初始化操做。