本文以 Eric Matthes 的《Python编程:从入门到实践》为基础,以有一定其他语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章。

读完本篇文章后,可对 Python 语言特性、编码风格有一定了解,并可写出简单的 Python 程序。

一、安装与运行

各个系统的 Python 安装教程请自行查阅资料,这里不再赘述。

检查 Python 版本,在命令行输入 python 即可,同时会进入命令行交互模式,可以在这里执行 python 命令。

如果电脑中安装了 python2.x 和 python3.x 两个版本,输入 python 运行的是 2.x 版本。想运行 3.x,则需输入 python3

在命令行输入 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 :

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() 即可退出命令行模式。

命令行运行 python 文件

如果是写好了一个 python 文件,想通过命令行运行它,进入这个目录,在命令行输入 python 文件名.py 即可。

比如桌面上有个文件 hello.py,内容是打印一句话:

print("Hello, Python")

想运行它,先进入 Desktop 目录,再在命令行输入 python hello.py 就能运行:

Solo-mac:Desktop solo$ python hello.py
Hello, Python

二、变量和简单数据类型

2.1 变量命名规则

  • 变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头,但不能以数字打 头,例如,可将变量命名为message_1,但不能将其命名为1_message。
  • 变量名不能包含空格,但可使用下划线来分隔其中的单词。例如,变量名greeting_message 可行,但变量名greeting message会引发错误。
  • 不要将Python关键字和函数名用作变量名,即不要使用Python保留用于特殊用途的单词, 如print。
  • 变量名应既简短又具有描述性。例如,name比n好,student_name比s_n好,name_length比length_of_persons_name好。
  • 慎用小写字母l和大写字母O,因为它们可能被人错看成数字1和0。

变量名应该是小写的,虽然没有强制规定,但是约定俗称的规则。

2.2 字符串

字符串就是一系列字符。在Python中,用引号括起的都是字符串,其中的引号可以是单引号,也可以是双引号,还可以同时使用。如:

"This is a string."
'This is also a string.'
"I love 'python'"

2.2.1 字符串的简单运算

下面介绍字符串的简单运算。

title()

title()以首字母大写的方式显示每个单词,即将每个单词的首字母都改为大写。

>>> name = 'solo coder'
>>> name.title()
'Solo Coder'
upper()、lower()

将字符串改为全部大写或全部小写。

>>> name
'solo coder'
>>> name.upper()
'SOLO CODER'
>>> name.lower()
'solo coder'
>>> name
'solo coder'

注意:title()、upper()、lower() 均不改变原字符串,只是输出了一个新的字符串。

2.2.2 合并(拼接)字符串

Python使用加号(+)来合并字符串。

>>> first = 'solo'
>>> last = 'coder'
>>> full = first + ' ' + last
>>> full
'solo coder'

2.2.3 使用制表符或换行符来添加空白

在编程中,空白泛指任何非打印字符,如空格、制表符和换行符。

要在字符串中添加制表符,可使用字符组合 \t,要在字符串中添加换行符,可使用字符组合 \n 。

>>> print('\tPython')
Python
>>> print('Hello,\nPython')
Hello,
Python

2.2.4 删除空白

rstrip() 删除右侧空白,lstrip() 删除左侧空白,strip() 删除两端空白。

>>> msg = ' Python '
>>> msg
' Python '
>>> msg.rstrip()
' Python'
>>> msg.lstrip()
'Python '
>>> msg.strip()
'Python'
>>> msg
' Python '

注意执行完去空格命令后,再打印出 msg,还是原来的字符串,这说明 strip() 也不改变原来的字符串。

2.2.5 Python 2 中的 print 语句

在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语句包含括号,有些不包含。

2.3 数字

2.3.1 整数

在Python中,可对整数执行加(+)减(-)乘(*)除(/)运算。

>>> 2 + 3
5
>>> 3 - 2
1
>>> 2 * 3
6
>>> 3 / 2
1.5

Python还支持运算次序,因此你可在同一个表达式中使用多种运算。你还可以使用括号来修 改运算次序,让Python按你指定的次序执行运算,如下所示:

>>> 2 + 3*4
14
>>> (2 + 3) * 4 20

2.3.2 浮点数

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会尽力找到一种方式,以尽可能精确地表示结果,但鉴于计算机内部表示数字的方式,这在有些情况下很难。后面将会学习更多的处理方式。

2.3.3 使用函数str()避免类型错误

如果用数字跟字符串拼接,就会出现类型错误。为避免这个问题,可以使用 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

2.3.4 Python 2 中的整数

在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时,这种除法行为常常会令人迷惑。使用或编写同时使用浮点数和整数的代码时,一定要注意这种异常行为。

2.3.5 注释

在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] 是获取倒数第二个元素。

3.1 列表的增删改查

3.1.1 修改元素

修改元素直接用索引修改

>>> list[0] = 'nihao'
>>> list
['nihao', 'heihei', 'hehe']

3.1.2 添加元素

可以在末尾添加,也可以在任意位置插入。

在末尾添加:append

>>> list.append('wa')
>>> list
['nihao', 'heihei', 'hehe', 'wa']

插入:insert

>>> list.insert(1, 'hello')
>>> list
['nihao', 'hello', 'heihei', 'hehe', 'wa']

3.1.3 删除元素

删除有三种方式:

  • del:按索引删除
  • pop():删除列表最后一个元素并返回最后一个元素的值。也可以传索引删除任意位置的值。
  • remove():按值删除
>>> 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()。

3.2 组织列表

本节将介绍列表的排序、反转、计算长度等操作。

列表的排序主要有两种方式:

  • 使用方法sort()对列表进行永久性排序
  • 使用函数sorted()对列表进行临时排序

3.2.1 使用方法sort()对列表进行永久性排序

使用 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']

3.2.2 使用函数sorted()对列表进行临时排序

函数 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']

3.2.3 反转列表

要反转列表元素的排列顺序,可使用方法 reverse()。 reverse() 也会改变原始列表。

reverse() 只会按原来的顺序反转,不会进行额外的按字母排序。

>>> list
['douglas', 'alex', 'solo', 'super']
>>> list.reverse()
>>> list
['super', 'solo', 'alex', 'douglas']

3.2.4 确定列表的长度

使用函数len()可快速获悉列表的长度。

>>> list
['super', 'solo', 'alex', 'douglas']
>>> len(list)
4

3.3 操作列表

3.3.1 循环

使用 for…in 循环。

python 以缩进来区分代码块,所以需要正确的缩进

>>> cats
['super', 'solo', 'alex', 'douglas']
>>> for cat in cats:
... print(cat)
...
super
solo
alex
douglas

3.3.2 range()

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]

3.3.3 对列表简单的计算

有几个专门用于处理数字列表的Python函数。

  • min():计算最小值
  • max():计算最大值
  • sum():计算总和
>>> numbers
[1, 2, 3, 4, 5]
>>> min(numbers)
1
>>> max(numbers)
5
>>> sum(numbers)
15

3.3.4 列表解析

列表解析将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 语句末尾没有冒号。

3.4 切片

要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数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

3.5 复制列表

可以使用切片来快速复制列表,不指定开始索引和结束索引。

>>> 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']

3.6 元组

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 语句

简单的 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对象用作字典中的值。

5.1 字典的增删改查

使用字典

在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}

5.2 遍历字典

字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键—值对、键或值。

遍历所有键值对 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

5.3 嵌套

可以在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。这里就不演示了。

六、用户输入和while循环

6.1 用户输入

函数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() 来转换。

6.2 while 循环

for循环用于针对集合中的每个元素都一个代码块,而while循环不断地运行,直到指定的条件不满足为止。

>>> num = 1
>>> while num <= 5:
... print(str(num))
... num += 1
...
1
2
3
4
5

break

要立即退出while循环,不再运行循环中余下的代码,也不管条件测试的结果如何,可使用break语句。break语句用于控制程序流程,可使用它来控制哪些代码行将执行,哪些代码行不执行,从而让程序按你的要求执行你要执行的代码。

continue

要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue语句,它不像 break 语句那样不再执行余下的代码并退出整个循环。

七、函数

Python 用关键字 def 来定义函数,函数名以冒号 : 结尾,冒号之后的缩进里的内容都是函数体。

>>> def greet():
... print('Hello World!')
...
>>> greet()
Hello World!

7.1 函数参数

可以向函数传递参数。下面的例子向函数 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依然能够正确地解读位置实参。

7.2 返回值

函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回 的值被称为返回值。在函数中,可使用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}

7.3 传递任意数量的实参

有时候,你预先不知道函数需要接受多少个实参,好在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}

7.4 导入导出

可以将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。import语句允许在当前运行的程序文件中使用模块中的代码。

7.4.1 导入整个模块

模块是扩展名为.py的文件,包含要导入到程序中的代码。

def eat(food):
print('I am cat, I eat ' + food)
import cat

cat.eat('fish')

控制台输出

I am cat, I eat fish

7.4.2 导入特定的函数

你还可以导入模块中的特定函数,这种导入方法的语法如下:

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')

得到相同的结果。

7.4.3 使用 as 给函数指定别名

如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名——函数的另一个名称,类似于外号。要给函数指定这种特殊外号,需要在导入它时这样做。

from cat import eat as cat_eat

cat_eat('fish')

将 cat.py 中的 eat() 方法导入并指定了别名 cat_eat,使用时可以直接用别名使用。

7.4.4 使用 as 给模块指定别名

你还可以给模块指定别名。通过给模块指定简短的别名,让你 能够更轻松地调用模块中的函数。

通用语法:import module_name as mn

import cat as c

c.eat('fish')

7.4.5 导入模块中的所有函数

使用星号(*)运算符可让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 可能遇到多个名称相同的函数或变量,进而覆盖函数,而 不是分别导入所有的函数。

最佳的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。这能 让代码更清晰,更容易阅读和理解。

7.5 函数编写指南

  • 应给函数指定描述性名称

  • 函数名应只包含小写字母和下划线

  • 每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式。

  • 给形参指定默认值时,等号两边不要有空格:

    def function_name(parameter_0, parameter_1='default value')
    
    

    对于函数调用中的关键字实参,也应遵循这种约定:

    function_name(value_0, parameter_1='value')
    
    
  • 如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。

  • 所有的import语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序。

八、类

8.1 创建和使用类

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中创建类

在Python 2.7中创建类时,需要做细微的修改——在括号内包含单词object:

class ClassName(object):

8.2 类的属性

8.2.1 给属性设置默认值

类中的每个属性都必须有初始值,哪怕这个值是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))

8.2.2 修改属性的值

可以以三种不同的方式修改属性的值:直接通过实例进行修改,通过方法进行设置。

1. 直接修改属性的值

要修改属性的值,最简单的方式是通过实例直接访问它。

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 属性的值。

2. 通过方法修改属性的值

再来更新代码,加入 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

8.3 继承

一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

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

Python2.7 中的继承

在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。

8.4 导入类

当一个文件过长时,可以将其中一部分代码抽离出去,然后导入到主文件中。

导入方式有多种:

  • 导入单个类

    假如 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语法 来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地 方使用了导入的模块;你还避免了导入模块中的每个类可能引发的名称冲突。

九、文件和异常

9.1 从文件中读取数据

要使用文本文件中的信息,首先需要将信息读取到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。

9.1.1 读取整个文件

with open('test.txt') as file_obj:
contents = file_obj.read()
print(contents)

open() 用于打开一个文件,参数为文件的路径。

关键字 with 在不再需要访问文件后将其关闭。有了 with 你只管打开文件,并在需要时使用它,Python自会 在合适的时候自动将其关闭。

相比于原始文件,该输出唯一不同的地方是末尾多了一个空行。为何会多出这个空行呢?因为 read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除多出来的空行,可在print语句中使用 rstrip()

文件路径可以是相对路径,也可以是绝对路径。

9.1.2 逐行读取

with open('test.txt') as file_obj:
for line in file_obj:
print(line.rstrip())

要以每次一行的方式检查文件,可对文件对象使用for循环。

9.2 写入文件

with open('test.txt', 'w') as file_obj:
file_obj.write("I love python")

在这个示例中,调用open()时提供了两个实参,第一个实参也是要打开的文件的名称;第二个实参(‘w’)告诉Python,我们要以写入模式打开这个文件。

可选模式:

  • r :只读。
  • w : 只写。如果文件不存在则创建,如果文件存在则先清空,再写入。
  • a :附加模式,写入的内容追加到原始文件后面。如果文件不存在则创建。
  • r+ :可读可写。

如果你省略了模式实参,Python将以默认的只读模式打开文件。

9.3 异常

异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。

try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")

else 代码块

try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print("no exception")

如果 try 中的代码运行成功,没有出现异常,则执行 else 代码块中的代码。

9.4 用 json 存储数据

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_打头的方法。

通常用于做一些初始化操作。

十分钟快速入门 Python,看完即会,不用收藏!的更多相关文章

  1. python视频教程:十分钟快速入门python

    想要学习python这门语言,却始终找不到一个全面的Python视频教程,倘若你是真心想学好一门语言,小编建议你亲自动手实践的.下面来看看入门python的学习教程. Python的语言特性 Pyth ...

  2. 十分钟快速入门 Python

    本文以 Eric Matthes 的<Python编程:从入门到实践>为基础,以有一定其他语言经验的程序员视角,对书中内容提炼总结,化繁为简,将这本书的精髓融合成一篇10分钟能读完的文章. ...

  3. 快速入门python看过的一些资料

    我快速入门python看过的一些资料 B站的视频 10天自学Python,轻松掌握Python基础[千锋] 廖雪峰 - Python教程 https://www.liaoxuefeng.com/wik ...

  4. 程序员带你十天快速入门Python,玩转电脑软件开发(四)

    本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...

  5. 程序员带你十天快速入门Python,玩转电脑软件开发(三)

    声明:本次教程主要适用于已经习得一门编程语言的程序员.想要学习第二门语言.有梦想,立志做全栈攻城狮的你 . 如果是小白,也可以学习本教程.不过可能有些困难.如有问题在文章下方进行讨论.或者添加QQ群5 ...

  6. 程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  7. 程序员带你十天快速入门Python,玩转电脑软件开发(一)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  8. Mysql快速入门(看完这篇能够满足80%的日常开发)

    这是一篇mysql的学习笔记,整理结合了网上搜索的教程以及自己看的视频教程,看完这篇能够满足80%的日常开发了. 菜鸟教程:https://www.runoob.com/mysql/mysql-tut ...

  9. 十天快速入门Python

    课程导学 001 课程定位和目标 002 课程导学 第一部分 Python快速入门 第1天 Python基本语法元素 003 Python基本语法元素 004 程序设计基本方法 005 Python开 ...

随机推荐

  1. Hadoop hadoop 机架感知配置

    机架感知脚本 使用python3编写机架感知脚本,报存到topology.py,给予执行权限 import sys import os DEFAULT_RACK="/default-rack ...

  2. 【caffe Blob】caffe中与Blob相关的代码注释、使用举例

    首先,Blob使用的小例子(通过运行结果即可知道相关功能): #include <vector> #include <caffe/blob.hpp> #include < ...

  3. [Windows] 输入字符间距变宽

    今天在输入时,不会到误触到哪里,输入的字符间距变得很宽,如下图: 最后找到原因是不小心同时按下了 Shift+Space(空格),进入全角模式,就会导致输入的字符间距变宽 想要恢复,再按一次 shif ...

  4. centos 普通用户 和 root 相互切换方法

    root 用户切换为普通用户 :用 login -f username (加 -f 不用输入密码)例如普通用户的用户名为hadoop,这里就是 login -f hadoop 普通用户切换为root用 ...

  5. nginx: [emerg] unknown directive "stub_status" in /home/oscf/nginx/conf/conf.d/ngx_metric.conf

    解压安装过程命令如下: cd /home/oscf #该目录下有nginx压缩包 mkdir nginx tar -zxvf nginx-1.16.0.tar.gz cd nginx-1.16.0 . ...

  6. C/C++/Linux编程经典电子书pdf下载

    实际上目前Linux下C开发一般都是C++实现下的C,而不是最纯粹的C,使用g++而不是gcc编译,所以直接学习C++的过程性C部分是更加高效的. C++ Primer(中文版 第5版)C++学习头牌 ...

  7. ntpd服务

    yum -y install ntp 服务器端 [root@ip-172-31-6-148~]# vim /etc/ntp.conf ...# Use public servers from thep ...

  8. android -------- GifView 显示gif图片

    最近的项目需要在界面显示Gif动图,查找网络资料,总结了一下,分享一下, 一个GifView的gif图加载库以有效地显示GIF, 您可以启动,暂停和停止gifView 在app 的 build.gra ...

  9. 让remix使用本地文件系统

    让remix使用本地文件系统   转:https://blog.csdn.net/platocnet/article/details/83376792 1. 测试发现使用npm命令安装相关环境不成功, ...

  10. 惠普打印机和扫描仪修复医生 HP Print and Scan Doctor

    https://support.hp.com/cn-zh/topic/printscandoctor-printing-problems http://ftp.hp.com/pub/printers/ ...