【转载】Python学习笔记
1 入门基础
1.1 标识符
标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。
以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:
_xxx
,表示不能直接访问的类属性,需通过类提供的接口进行访问,不能用from xxx import *
导入;- 双下划线开头的标识符,如:
__xx
,表示私有成员; - 双下划线开头和结尾的标识符,如:
__xx__
,表示 Python 中内置标识,如:__init__()
表示类的构造函数。
1.2 关键字
关键字表 | |||||
---|---|---|---|---|---|
and | exec | not | assert | finally | or |
break | for | pass | class | from | |
continue | global | raise | def | if | return |
del | import | try | elif | in | while |
else | is | with | except | lambda | yield |
上面表中是 Python 中的关键字(保留字),我们在自定义标识符时不能使用关键字。
1.3 数据类型
-
整数:可以为任意大小、包含负数
-
浮点数:就是小数
-
字符串:以单引号
'
、双引号"
、三引号'''
或"""
括起来的文本
引号的开始与结束须类型相同,三引号可以由多行组成。如下所示:
1 | id = '001' |
-
布尔:只有
True
、False
两种值 -
空值:用
None
表示 -
变量:是可变的
-
常量:不可变
1.4 输入输出
Python 输出使用 print(),内容加在括号中即可。如下所示:
1 | print('Hello Python') |
Python 提供了一个 input(),可以让用户输入字符串,并存放到一个变量里。如下所示:
1 | name = input() |
1.5 运算符
常用运算符
运算符 | 描述 | 示例 |
---|---|---|
+ | 相加 | a + b |
- | 相减 | a - b |
* | 相乘 | a * b |
/ | 相除 | a / b |
% | 取模 | a % b |
** | 幂 | a**b 表示 a 的 b 次幂 |
// | 取整除 | 9 // 4 结果为 2 |
== | 是否相等 | a == b |
!= | 是否不等于 | a != b |
> | 是否大于 | a > b |
>= | 是否大于等于 | a >= b |
<= | 是否小于等于 | a <= b |
= | 简单的赋值运算符 | a = b + c |
+= | 加法赋值运算符 | a += b 等效于 a = a + b |
-= | 减法赋值运算符 | a -= b 等效于 a = a - b |
*= | 乘法赋值运算符 | a *= b 等效于 a = a * b |
/= | 除法赋值运算符 | a /= b 等效于 a = a / b |
%= | 取模赋值运算符 | a %= b 等效于 a = a % b |
**= | 幂赋值运算符 | a **= b 等效于 a = a ** b |
//= | 取整除赋值运算符 | a //= b 等效于 a = a // b |
& | 与 | a & b |
丨 | 或 | a 丨 b |
^ | 异或 | a ^ b |
~ | 取反 | ~a |
<< | 左移动 | a << 3 |
>> | 右移动 | a >> 3 |
and | 布尔类型与 | a and b |
or | 布尔类型或 | a or b |
not | 布尔类型非 | not a |
is | 判断两个标识符是否引用同一个对象 | a is b |
is not | 判断两个标识符是否引用不同对象 | a is not b |
运算符优先级
运算符 | 描述(由上至下对应优先级由高到低) |
---|---|
** | 幂运算 |
~ + - | 取反、正号、负号 |
* / % // | 乘、除、取模、取整除 |
+ - | 加法、减法 |
>> << | 右移、左移 |
& | 与 |
^ 丨 | 异或、或 |
<= < > >= | 比较运算符 |
== != | 是否等于、是否不等于 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
1.6 缩进
Python 不使用 {}
来控制类、函数、逻辑判断等,而是使用缩进,缩进的空格可变。如下所示:
1 | if True: |
1.7 多行
Python 中一般以新行作为语句的结束标识,可以使用 \
将一行语句分为多行显示。如下所示:
1 | a = 128 |
如果包含在 []
、{}
、()
括号中,则不需要使用 \
。如下所示:
1 | arr = { |
1.8 注释
Python 中单行注释使用 #
,多行注释使用三个单引号('''
)或三个双引号("""
)。如下所示:
1 | # 我是单行注释 |
___________
2 基本语句
2.1 条件语句
在进行逻辑判断时,我们需要用到条件语句,Python 提供了 if
、elif
、else
来进行逻辑判断。格式如下所示:
1 | if 判断条件1: |
2.2 循环语句
当需要多次重复执行时,我们要用到循环语句,Python 提供了 for 循环和 while 循环。
2.2.1 for循环
for 循环可以遍历任何序列,比如:字符串。如下所示:
1 | str = 'Python' |
输出结果:
1 | P |
如果你对for循环很感兴趣,可以尝试一下下面这个有意思的小程序。
1 | import time |
2.2.2 while循环
while 循环,满足条件时进行循环,不满足条件时退出循环。如下所示:
1 | sum = 0 |
输出结果:
1 | 55 |
2.2.3 break
break 用在 for 循环和 while 循环语句中,用来终止整个循环。如下所示:
1 | str = 'Python' |
输出结果:
1 | P |
2.2.4 continue
continue 用在 for 循环和 while 循环语句中,用来终止本次循环。如下所示:
1 | str = 'Python' |
输出结果:
1 | P |
2.3 空语句
pass 是空语句,它不做任何事情,一般用做占位语句,作用是保持程序结构的完整性。如下所示:
1 | if True: |
___________
3 数据类型
3.1 数值
3.1.1 数值类型
Python有三种数值类型,分别是:整型(int)、浮点型(float)、复数(complex),在低版本Python2中,还包含长整型(long)。
- 整型:包括正整数、负整数。如:1024、-1024。整型有四种进制表示,分别为:二进制、八进制、十进制、十六进制,说明如下表所示:
种类 | 描述 | 引导符 |
---|---|---|
二进制 | 由 0 和 1 组成 | 0b 或 0B |
八进制 | 由 0 到 7 组成 | 0o 或 0O |
十进制 | 默认情况 | 无 |
十六进制 | 由 0 到 9、a 到 f、A 到 F 组成,不区分大小写 | 0x 或 0X |
-
浮点型:由整数部分和小数部分组成。
-
复数:由实数部分和虚数部分组成。
-
分数:需要载入Fraction模块,如:
1 | from fractions import Fraction |
结果输出:
1 | 1/12 |
3.1.2 基本运算
我的基本运算见下表,整型和浮点型均支持下表中运算。
运算 | 描述 |
---|---|
x + y | x 和 y 的和 |
x - y | x 和 y 的差 |
x * y | x 和 y 的乘积 |
x / y | x 和 y 的商 |
x // y | x 除以 y,取整除 |
x % y | x 除以 y,取模 |
-x | x 取反 |
+x | x 不变 |
abs(x) | x 的绝对值 |
int(x) | 将 x 转换为整数 |
float(x) | 将 x 转换为浮点数 |
complex(x, y) | 一个带有实部 x 和虚部 y 的复数,y 默认为 0。 |
divmod(x, y) | (x // y, x % y) |
pow(x, y) | x 的 y 次幂 |
x ** y | x 的 y 次幂 |
3.1.3 数学函数
除了上面的基本运算外,我还可以借助数学模块 math
实现更多的运算。首先要先引入数学模块 math
。如下所示:
1 | import math |
引入之后就可以使用了,以 math
模块中求平方根函数 sqrt(x)
为例。使用方式如下所示:
1 | import math |
math
模块中除了求平方根函数,还有很多可以使用的函数。如下表所示:
函数 | 描述 |
---|---|
abs(x) | 返回 x 的绝对值 |
ceil(x) | 返回 x 的上入整数,如:math.ceil(1.1) 返回 2 |
floor(x) | 返回 x 的下舍整数,如:math.floor(1.1) 返回 1 |
exp(x) | 返回 e 的 x 次幂 |
log(x) | 返回以 e 为底 x 的对数 |
log10(x) | 返回以 10 为底 x 的对数 |
pow(x, y) | 返回 x 的 y 次幂 |
sqrt(x) | 返回 x 的平方根 |
factorial(x) | 返回 x 的阶乘 |
3.1.4 随机函数
在安全领域有时会用到随机数,random
模块对随机数的生成提供了支持。首先还是要引入 random
模块。如下所示:
1 | import random |
下面简单介绍两个函数:random(x)函数随机生成一个 0 到 1 范围内的实数。使用如下所示:
1 | import random |
uniform(x, y)函数随机生成一个 x 到 y 范围内的实数。使用如下所示:
1 | import random |
3.2 字符串
字符串是 Python 的一种数据类型,它可以通过单引号 ‘、双引号 "、三引号 ‘’’ 或 “”" 来定义,本节我们将展开介绍。
3.2.1 访问操作
访问单个字符可以将字符串视为数组
1 | s = 'Python' |
访问范围内字符用:
来连接首位指针
1 | s = 'Python' |
3.2.2 查询编码
Python 使用了 ord()
函数返回单个字符的ASCII码,chr()
函数把编码转成相应字符。如:
1 | s = 'A' |
输出结果:
1 | 65 |
3.2.3 转义符
之前我们说过可以通过反斜杠 \
将一行语句分多行显示,其实就是 \
来转义字符,一些常见的转义字符如下表所示:
转义字符 | 描述 |
---|---|
\ |
在行尾使用时,用作续行符 |
\b | 退格(Backspace) |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
3.2.4 运算符
之前我们已经介绍了大部分运算符,下面再来详细看一下字符串运算符。如下表所示:
运算符 | 描述 |
---|---|
+ | 连接符 |
* | 重复输出 |
[] | 通过索引获取字符串中字符 |
[ : ] | 获取字符串中的一部分 |
in | 字符串中是否包含指定字符 |
not in | 字符串中是否不包含指定字符 |
r/R | 字符串原样输出 |
使用示例如下所示:
1 | s1 = 'Hello' |
输出结果:
1 | s1 + s2 --> HelloPython |
3.2.5 格式化输出
当我们需要输出的内容中含有变量时,比如:Hello xxx
,xxx
为变量,此时便需要一种格式化字符串的方式,Python 使用 %
格式化字符串,常用占位符如下表所示:
占位符 | 描述 |
---|---|
%s | 格式化字符串 |
%d | 格式化整数 |
%f | 格式化浮点数 |
以字符串为例,如下所示:
1 | print('Hello %s' % 'Python') |
输出结果:
1 | Hello Python |
我们也可以使用字符串的 format()
方法进行格式化,先看下示例:
1 | print('{0} {1}'.format('Hello', 'Python')) |
这种方式是用传入的参数依次替换字符串内的占位符{0}、{1} …
___________
4 向量
4.1序列
Python中的序列
是一块可存放多个值的连续内存空间
,类似于C中的数组,其所有值按一定顺序排列,每个值所在位置都有一个编号,称其为索引
,我们可以通过索引访问其对应值。我们上一节说的字符串就是一种典型的序列结构。
4.1.1 索引
序列索引支持非负数和负数,索引为非负数,从 0
开始,由左向右计数如:
索引为负数由右向左计数,从 -1
开始,如:
下面通过一个示例作进一步了解,以字符串为例,如下所示:
1 | >>>str = '贝蒂小熊,乱世不败' |
从结果来看,我们使用非负数索引与负数索引得到的结果一致。
4.1.2 切片
切片操作可以访问一定范围内的元素,语法如下所示:sname[start : end : step]
- sname:表示序列的名称;
- start:开始索引位置**(包括该位置)**,默认为 0;
- end:表示切片的结束索引位置**(不包括该位置)**,默认为序列的长度;
- step:步长。
以字符串为例,如下所示:
1 | >>>str = '贝蒂小熊,乱世不败' |
4.1.3 相加
Python支持类型相同的序列使用 +
作相加操作,该操作不会去除重复的元素。以字符串为例,如下所示:
1 | >>>str1 = '贝蒂小熊' |
4.1.4 相乘
Python中,使用数字 n 乘以一个序列会生成新的序列,内容为原来序列被重复 n 次的结果。以字符串为例,如下所示:
1 | >>>str = '贝蒂小熊n' |
4.1.5查询
Python使用 in
关键字检查某元素是否为序列的成员,语法如下:val in seq
- val:要检查的元素;
- seq:指定的序列。
通过一个例子作进一步了解,以字符串为例,如下所示:
1 | >>>str = '贝蒂小熊,乱世不败' |
4.1.6 内置函数
函数 | 描述 |
---|---|
len() | 计算序列的长度 |
max() | 找出序列中的最大元素 |
min() | 找出序列中的最小元素 |
list() | 将序列转换为列表 |
str() | 将序列转换为字符串 |
sum() | 计算元素的和 |
sorted() | 对元素进行排序 |
enumerate() | 将序列组合为一个索引序列,多用在 for 循环中 |
简单举几个例子,如下所示:
1 | >>>c = [6,5,4,7,2] |
4.2 列表
Python中没有数组,而是加入了功能更强大的列表(list),列表可以存储任何类型的数据,同一个列表中的数据类型还可以不同;列表是序列结构,可以进行序列结构的基本操作:索引、切片、加、乘、检查成员。
4.2.1 创建
列表中所有元素都放在一个中括号 []
中,相邻元素之间用逗号 ,
分隔,如下所示:
1 | >>>l = [1024, 0.618, '贝蒂小熊'] |
4.2.2 访问
通过索引访问列表中的值,还可以使用 :
截取范围内的元素,如下所示:
1 | >>>l = [1024, 0.618, '贝蒂小熊'] |
4.2.3 更新
修改列表的已有元素可以用直接赋值的方法:
1 | >>>l = [1024, 0.618, '贝蒂小熊'] |
添加新元素使用 append()
函数,如:
1 | >>>l = [1024, 0.618, '贝蒂小熊'] |
删除列表中元素使用 del
函数,如下所示:
1 | >>>l = [1024, 0.618, '贝蒂小熊'] |
4.2.4 其他函数
count()
统计列表中某个元素出现的次数,使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
index()
查找某个元素在列表中首次出现的位置(即索引),使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
remove()
移除列表中某个值的首次匹配项,使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
sort()
对列表中元素进行排序,使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
copy()
复制列表,使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
4.3 元组
元组(tuple)与列表类似,但元组是不可变的,可简单将其看作是不可变的列表,元组常用于保存不可修改的内容。
4.3.1 创建
元组中所有元素都放在一个小括号 ()
中,相邻元素之间用逗号 ,
分隔,如下所示:
1 | >>>t = (1024, 0.5, 'Python') |
4.3.2 访问
与访问列表中元素类似,如:
1 | >>>t = (1024, 0.5, 'Python') |
4.3.3 更新
元组中元素不能被修改,我们要用重新赋值的方式操作,如下所示:
1 | >>>t = (1024, 0.5, 'Python') |
元组中的元素不能被删除,我们只能删除整个元组,如下所示:
1 | >>>t = (1024, 0.5, 'Python') |
由于元组实例被删除,所以输出了异常信息。
4.3.4 其他函数
len()
计算元组中元素个数,使用如下所示:
1 | >>>t = (1024, 0.5, 'Python') |
ma\()
和min()
返回元组中元素最大、最小值,使用如下所示:
1 | >>>t = ('d', 'b', 'a', 'f', 'd') |
tuple()
将列表转换为元组,使用如下所示:
1 | >>>l = ['d', 'b', 'a', 'f', 'd'] |
4.4 字典
Dict是Python的一种数据结构,它的内容都是以键-值(key-value)的方式存在的。Dict拥有良好的查询速度,Dict中的值可以是任意Python对象,多次对一个key赋value,后面的value会把前面的value覆盖。
4.4.1 使用
字典的内容在花括号 {}
内,键-值(key-value)之间用冒号 :
分隔,键值对之间用逗号 ,
分隔,比如创建字典 d,如下所示:
1 | # 方式一 |
字典中的值通过 key 进行访问,如下所示:
1 | dict(name='小明', age='18') d = |
4.4.2 更新
修改操作,以修改 age 为例,如下所示:
1 | dict(name='小明', age='18') d = |
清空集合,如下所示:
1 | dict(name='小明', age='18') d = |
4.4.3 其他函数
获取字典的长度,如下所示:
1 | dict(name='小明', age='18') d = |
4.5 集合
集合(set)与字典相同均存储 key,但也只存储 key,因 key 不可重复,所以 set 的中的值不可重复,也是无序的。
4.5.1 使用
集合使用花括号 {}
或者 set()
函数创建,如果创建空集合只能使用 set()
函数,以创建集合 s 为例,如下所示:
1 | >>>s = {'a', 'b', 'c'} |
集合中重复的元素会被自动过滤掉,如下所示:
1 | 'a', 'a', 'b', 'c', 'c'} s = { |
4.5.2 更新
添加元素可以使用 add
或 update
方法,如果元素已经存在,则不进行操作,如下所示:
1 | 'a', 'b', 'c'} s = { |
删除元素使用 remove
方法,如下所示:
1 | 'a', 'b', 'c'} s = { |
清空集合使用 clear
方法,如下所示:
1 | 'a', 'b', 'c'} s = { |
4.5.3 其他函数
获取集合的长度,同样使用 len
方法,如下所示:
1 | 'a', 'b', 'c'} s = { |
5 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
5.1 自定义函数
5.1.1 函数定义
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
- 注意缩进格式
1 | def functionname( parameters ): |
如:以下为一个简单的Python函数,它将一个字符串作为传入参数,再打印到标准显示设备上。
1 | def printme(str): |
5.1.2 函数调用
定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。
这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。
如下实例调用了printme()函数:
1 | "博博博博博博博哥") printme( |
5.1.3 返回值
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。如:
1 | def sum( arg1, arg2 ): |
5.2 参数
以下是调用函数时可使用的正式参数类型:
必备参数
关键字参数
默认参数
不定长参数
5.1.1 必备参数
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
如调用printme()函数,你必须传入一个参数,不然会出现语法错误:
1 | printme() |
5.1.2 关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为Python解释器能够用参数名匹配参数值。
以下实例在函数 printme() 调用时使用参数名:
1 | str = "琅琊少年诸葛恪") printme( |
关键字参数具有顺序不重要性:
1 | def whatsup(name, value): |
5.1.3 默认参数
调用函数时,默认参数的值如果没有传入,则被认为是默认值。如:
1 | def whatsup(name="八卦阵", value="♠8"): |
5.1.4 不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
1 | def functionname([formal_args,] *var_args_tuple ): |
加了星号(*)的变量名会存放所有未命名的变量参数。如:
1 | def printlist(name,*vars): |
5.3 参数类型
在 python 中,类型属于对象,变量是没有类型的:
1 | 1,2,3] a=[ |
以上代码中,[1,2,3]是List类型,"哈哈哈"是String类型,而变量a没有类型,它仅仅是一个对象的引用(一个指针),可以是List类型对象,也可以指向String类型对象。
5.3.1 可更改/不可更改对象
在 python 中,strings,tuples和numbers是不可更改的对象,而list,dict等则是可以修改的对象。
**不可变类型:**变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
**可变类型:**变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
5.3.2 参数传递
**不可变类型:**类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。如:
1 | def ChangeInt(a): |
实例中有int对象2,指向它的变量是b,在传递给ChangeInt()函数时,按传值的方式复制了变量b,a和b都指向了同一个Int对象,在a=10时,则新生成一个int值对象10,并让a指向它。
就是说这段代码你白写了。
**可变类型:**类似 c++ 的引用传递,如 列表,字典。如fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
1 | def ChangeList(lis): |
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
5.4 匿名函数
5.4.1 lambda
lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数。
有些函数在代码中只用一次,而且函数体比较简单,使用匿名函数可以减少代码量,看起来比较“优雅”。
5.4.2 语法
lambda函数的语法只包含一个语句,如下:
1 | lambda [arg1 [,arg2,.....argn]]:expression |
举例:
1 | # 普通函数 |
然而更常见的用法是将匿名函数与其他函数配合使用。
5.4.3 和map函数
map()
函数接收两个参数,一个是作用函数,一个是Iterable,map()将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回遍历序列,对序列中每个元素进行函数操作,最终获取新的序列。
例:求列表[1,2,3,4,5,6,7,8,9]返回一个n*n的列表。
1 | #一般解决方案 |
5.4.4 和reduce函数
reduce
把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(func,[1,2,3]) 等同于 func(func(1,2),3)。
例:计算序列[1,2,3,4,5,6,7,8,9]的积。
1 | from functools import reduce |
5.4.5 和filter函数
filter()
也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
对于序列中的元素进行筛选,最终获取符合条件的序列。
1 | # 在一个list中,删掉偶数,只保留奇数 |
5.4.6 和sorted函数
sorted(iterable, key, reverse)函数接收一个key函数来实现对可迭代对象进行自定义的排序
iterable:主要有列表,字符串,元祖,集合和字典
key:接受一个函数,根据此函数返回的结果,进行排序
reverse:排序方向,默认为从小到大,reverse=True为从大到小
与sort()函数不同的是,sort()函数的返回值是在原序列基础上的排列,而sorted()返回一个新的序列。
1 | # 假设我们用一组tuple表示学生名字和成绩: |
6 模块与包
6.1 模块
6.1.1 简介
模块化是将程序分解为一个个的模块module,通过组合模块来搭建出一个完整的程序,便于团队开发,方便维护和代码复用。
在python中一个脚本(.py)文件就是一个模块,创建模块实际上就是创建一个.py文件,可以被其他模块导入并使用。注:
自定义模块的时候要注意命名的规范,使用小写,不要使用大写,不要使用中文,不要使用特殊字符等。
不要与内置模块冲突如sys等。
在同一个包中的模块名不允许重复,在不同包中的允许重复。
- 先创建一个package(包),再建一个文件
1 | `# 在模块中定义变量 |
6.1.2 使用模块
确保和定义模块处于同一个package,然后建立新的文件。
导入模块的2种方式:
方式一:import 包名.模块名 [as 别名] (别名可要可不要)
方式二: from 包名 import 模块名
from 包名.模块名 import 变量|函数|类
注:导入模块的代码可以放在任意位置,但一般都放在程序的开头。
1 | # 方式一,不定义别名 |
6.2 包
6.2.1 基础
为了方便归类整理和避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
举个例子,一个zhaoyun.py的文件就是一个名字叫zhaoyun的模块,一个machao.py的文件就是一个名字叫machao的模块。
现在,假设我们的zhaoyun和machao这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如shu,按照如下目录存放:
1 | mycompany |
引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,zhaoyun.py模块的名字就变成了shu.zhaoyun,类似的,machao.py的模块名变成了shu.machao。
每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是shu。
类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:
1 | sanguosha |
6.2.2 标准库
Python提供了一个强大的标准库,内置了许多非常有用的模块,可以直接使用,不用单独安装。
完整的库及介绍可以见官网:`https://docs.python.org/zh-cn/3/library/index.html
如果嫌官方太麻烦,可以看:https://www.cnblogs.com/jiangchunsheng/p/9275881.html,https://www.cnblogs.com/aipiaoborensheng/p/7813087.html,
https://blog.51cto.com/12402007/2164567`
这里说明一下标准库或第三方库的使用方法:
格式: import库名(文件顶端导入库)
引用:库名.功能 即可
如:
- sys:获取python解析的信息
- os:对操作系统进行访问,主要是对目录或文件操作
- math:数学运算
- random:生成随机数
- datetime:处理日期和时间,提供了多个类(dimedelta是处理时间类)
- time:处理时间,关于时间加减 可以参考:https://blog.csdn.net/xieganyu3460/article/details/82229039
1 | import sys |
6.2.3 第三方包
PYthon社区提供了大量的第三方包,使用方式与标准库类似。
安装第三方包:
1、使用包管理工具:pip(随python一起安装的)
语法:pip install 模块名
使用方法参考:https://jingyan.baidu.com/article/466506583fec5af549e5f825.html
2、使用pycharm 来安装:
方法:file-settings(设置)-Project:python-Project Interpreter
注意要选择当前版本:
安装新模块:
搜索模块名并安装:
成功安装界面:
pycharm安装报错处理方法:
报错信息:
问题说明:是因为pychram 安装脚本有问题。
处理方法:退出pycharm,右键pycharm-属性-打开安装位置
打开以后默认在bin目录,返回上一级-打开plugins-python-helpers目录-编辑packaging_tool.py文件
如果找不到这个目录:在安装目录首页搜索:packaging
定位到packaging_tool.py文件后
右键打开方式-写字板打开-找到 do_install
我的上面是正常的,把你的这2个内容全部删了,替换为
1 | `def do_install(pkgs): |
替换完以后重写打开pycharm并重新安装模块即可。
如果替换为上面的不行则用下面的
1 | `def do_install(pkgs): |
注意格式:如果放进去格式乱了,用其他文件打开,notepad或者pycharm打开把
默认是在python官网下载的模块(如果模块较大,可能会比较慢),可以更改下载源
比如https://pypi.python.org/simple
改成https://pypi.douban.com/simple
6.2.4 pyecharts的使用
百度搜索:echarts
,点击实例,你可以发现一个很骚气的东西
随便点开一个,发现,卧槽,还有代码,如果把这作为背景,这也太帅了把,当然,我臆想的而已,我现在还不知道这能不能作为网页之类的背景呢!!!!
pyecharts是一个用于Echarts图表的类库,便于在Python中根据数据生成可视化的图标,Echarts是百度开源的一个数据可视化JS库,主要用来进行数据可视化。
各种图标使用方式见官方(太炫酷了把):http://pyecharts.org/#/zh-cn/basic_charts?id=funnel%ef%bc%9a%e6%bc%8f%e6%96%97%e5%9b%be
使用前得先安装pyecharts模块:
使用前需要注意一个坑!!! 包名和文件名 不能有中文,否则 就会报错!!!
包和类全部无中文!!!
运行无报错以后,在同包下面会生成一个 html结尾的文件。
1 | `from pyecharts.charts import Bar |
现在运行 自动生成的.html结尾的文件!
就会打开一个网页,里面就是表格信息了!!!!
但是,我第二次弄的时候导包突然报错了!!!
葛优瘫坐在椅子上 深思 …
葛优瘫坐在椅子上 深思 …
突然想到,我包名是pyecharts , 模块是pyecharts。。我from导入的时候会不会系统默认给我导入我创建的这个包了啊???
我把我这个包名改了试试,报错。唉 果然不是这个问题啊!
难道是 文件名有错? demo01和其他包里的重复了? 我又把 文件名后面都加了个test,然后还是不行啊,我以为没生效,重启了软件,还是不行啊。哎 看来真出问题了。
都不行怎么办? 凉拌啊 凉了啊!!! 哎
要不重新导入模块试试,试试把 反正也就这样了!!!
咦? 可以了,我仔细看了一下,卧槽!!!! 就是我之前想的那样,导入的模块系统默认导入同名的包了!! 然后我改了包名,这名字也改了,没注意看啊!! 坑爹啊 坑爹啊!!! 细心点 细心点啊!!!
上诉能正常执行以后,参加:http://gallery.pyecharts.org/#/Map3D/map3d_china_base
这是官方给的 所有代码!!!
随便来几个官网中的代码测试:
demo1: 生成3D柱形图
执行方式,执行该代码就会自动生成一个html的文件,再打开自动生成的html即可
1 | `import random |
效果图:
demo2:三维地图
1 | `from pyecharts import options as opts |
运行结果: