1 python简介
python之父:
python的创始人为吉多·范罗苏姆(Guido van Rossum)(龟叔)。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹 打发时间,决心开发一个新的脚本解释程序,于是便有了python。
2018 年 python之父 退出决策层。
Python的官方介绍是:
Python是一种简单易学,功能强大的编程语言,它有高效率的高层数据结构,简单而有效地实现面向对象编程。Python简洁的语法和对动态输入的支持,再加上解释性语言的本质,使得它在大多数平台上的许多领域都是一个理想的脚本语言,特别适用于快速的应用程序开发。
python的广告词:人生苦短,我用python!
python能干什么:
运维、web开发、应用开发、大数据、数据挖掘、科学计算、机器学习、人工智能、自然语言处理等。
数据开发人员使用python做脚本,比如替代shell或者做爬虫
那谁最愿意使用这门语言,搞算法的,数据科学家。
python发展史:
1989年他创立了python语言。
1994年发布python1.0。
2000年发布python2.0。
2008年发布python3.0,不兼容python2.x 版本。
2010年发布python2.7,2020年停止更新。
2015年发布python3.5。
2019年发布python3.8。
python之禅:
Python之禅 by Tim Peters 【中文翻译版】
优美胜于丑陋(Python 以编写优美的代码为目标)
明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
可读性很重要(优美的代码是可读的)
即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)
当存在多种可能,不要尝试去猜测
而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )
做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)
2 python的特色
1)简单
Python是一种代表简单主义思想的语言。阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身。
2)易学
就如同你即将看到的一样,Python极其容易上手。前面已经提到了,Python有极其简单的语法。
3)免费、开源
Python是FLOSS(自由/开放源码软件)之一。简单地说,你可以自由地发布这个软件的拷贝、阅读它的源代码、对它做改动、把它的一部分用于新的自由软件中。FLOSS是基于一个团体分享知识的概念。这是为什么Python如此优秀的原因之一,因为它是由一群希望Python更加优秀的人创造并且这个社区十分活跃。
4)高级语言
当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节。
5)可移植性
因为 Python 是用 C 写的,又由于 C 的可移植性,使得 Python 被移植在许多平台上(经过改动使它能够工作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就可以在下述任何平台上面运行。
这些平台包括:Linux、Windows、FreeBSD、Macintosh、Solaris、OS/2、Amiga、AROS、AS/400、BeOS、OS/390、z/OS、Palm OS、QNX、VMS、Psion、Acom RISC OS、VxWorks、PlayStation、Sharp Zaurus、Windows CE甚至还有PocketPC!
6)解释性
编译型语言:编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言(二进制代码,即0和1)。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。
解释型语言:解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby。
一般来说,由于不是以本地机器码运行,纯粹的解释型语言要比编译型语言运行的慢。然而类似Python、java实际上是字节编译的,其结果就是可以生成一种近似机器语言的中间形式。这不仅改善了Python的性能,还同时使它保持了解释型语言的优点。
Python语言写的程序不需要编译成二进制代码,可以直接从源代码运行程序。在计算机内部,Python解释器把源代码转换成称为字节码的中间形式,然后再把它翻译成计算机使用的机器语言并运行。事实上,由于你不再需要担心如何编译程序,如何确保连接转载正确的库等等,所有这一切使得使用Python更加简单。由于你只需要把你的Python程序拷贝到另外一台计算机上,它就可以工作了,这也使得你的Python程序更加易于移植。
7)面向对象
Python即支持面向过程的编程也支持面向对象的编程。在 面向过程 的语言中,程序是由过程或仅仅是可重用代码的函数构建起来的。在 面向对象 的语言中,程序是由数据和功能组合而成的对象构建起来的。与其他主要的语言如C++和Java相比,Python以一种非常强大又简单的方式实现面向对象编程。
8)可扩展性
如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。
9)可嵌入性
你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能。
10)丰富的库
Python标准库确实很庞大。它可以帮助你处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。记住,只要安装了Python,所有这些功能都是可用的。这被称作Python的“功能齐全”理念。
3 python安装
3.1 Python安装
选择路径,安装
配置环境变量
在path 变量中加入Python目录
E:\Python37 (执行Python时需要配置)
E:\Python37\Scripts (执行pip时需要配置)
由于之前安装过python2版本,现在安装python3版本后,为了两个版本不冲突,需要修改python3的执行文件
将 E:\Python37目录下的 python.exe 复制文件名为 python3.exe
pythonw.exe 重名名为 pythonw3.exe
以后用python3运行python脚本的命令是 python3 xxx.py
查看Python 版本
3.2 pip安装
pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。
由于当前3.7.0版本安装包自带pip,当安装完成python3.7后,pip 和 pip依赖包 setuptools 已经安装完成。
pip 常用命令
# 安装xxx安装包
pip3 install xxx
# 查看已安装列表
pip3 list
# 卸载xxx安装包
pip3 uninstall xxx
如果网络比较慢,可以通过国内源安装和升级
# 用清华源在线安装xxx
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple xxx
# 用清华源在线【升级pip】
python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip
3.3 pip 安装 PyMySQL
PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库。
通过pip命令安装:
# 通过清华源安装
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple PyMySQL
查看已安装列表:
如果安装失败了,可以把目录里对应的文件或目录删掉,然后从已经安装好的同学那里copy过来放进去,可能会有惊喜。
pip 安装的目录
3.4 Python IDE安装和配置
1)安装IDE
是破解免安装版本,只需要解压到指定的目录下。
比如:
如果直接打开后,需要激活码,参考激活码文件
启动IDE,进入界面,创建工程
创建工程:File → New Project 进入创建界面,根据自己情况指定工程目录
进入开发主窗口
设置字体
注意:设置完,一定要点applay,否则设置不生效,后面的设置一样。
设置代码模板
# -*- encoding: utf-8 -*-
"""
${NAME}.py
Created on ${DATE} ${TIME}
Copyright (c) ${DATE}, 海牛学院版权所有.
@author: 潘牛
"""
设置工程、IDE、properties文件都是utf-8,设置后,代码里的中文是utf-8 编码
创建python文件,打印 hello world
运行hello_world.py 程序
右键选择
输出结果:
4 python基础
4.1 基本概念
Python 是个弱类型语言。
4.1.1 标识符的命名
● 标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘ _’)。
● 标识符名称的其他部分可以由字母(大写或小写)、下划线(‘ _ ’)或数字(0-9)组成。
● 标识符名称是对大小写敏感的。
● 在 Python 3 中,可以用中文作为变量名,非 ASCII 标识符也是允许的了。
有效 标识符名称的例子有i、__my_name、name_23和a1b2_c3。
无效 标识符名称的例子有2things、this is spaced out和my-name。
模块:py文件的命名
4.1.2 Number 数字
Python3 数字类型有4种: int、bool、float、complex(复数)。
在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
● int 表示长整型,如1,111111111。
● 布尔型,如True、False。
● 3.23和52.3E-4是浮点数的例子。E标记表示10的幂。在这里,52.3E-4表示52.3 * 10-4。
● (-5+4j)和(2.3-4.6j)是复数的例子。
>>> type(1)
<class 'int'>
>>> type(111111111111111111)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type(True)
<class 'bool'>
>>> type(5j+6)
<class 'complex'>
4.1.3 字符串
● python中单引号和双引号使用完全相同,Python 没有单独的字符类型,一个字符就是长度为 1 的字符串
● 使用三引号('''或""")表示多行字符串
● 用 \ 转义
● 自然字符串(r)
如果你想要指示某些不需要如转义符那样的特别处理的字符串,那么你需要指定一个自然字符串。自然字符串通过给字符串加上前缀r或R来指定。例如r"Newlines are indicatedby \n"。
● 连接打印(,)
● 连接字符串(+),复制字符串(*)
示例:
# python中单引号和双引号使用完全相同
>>> s1 = 'hainiu python'
>>> s2 = "hainiu python"
>>> print(s1)
hainiu python
>>> print(s2)
hainiu python
# 单引号套单引号需要用 \ 转义
>>> s3 = 'what\'s your name?'
>>> print(s3)
what's your name?
# 双引号套单引号不需要转义
>>> s4 = "what's your name?"
>>> print(s4)
what's your name?
# 如果想字符串内容不被\转义,可在字符串前加r
>>> path = 'e:\tmp\python'
>>> print(path)
e: mp\python
>>> path = r'e:\tmp\python'
>>> print(path)
e:\tmp\python
# 多行字符串
>>> s5 = '''hehe
... heihei'''
>>> print(s5)
hehe
heihei
>>> s6 = """heihei
... hehe"""
>>> print(s6)
heihei
hehe
# 用, 做字符串连接(拼接麻烦,不建议用)
>>> name = 'hainiu'
>>> age = 10
>>> print('name:',name,", age:", age)
name: hainiu , age: 10
# 用 + 只能做字符串连接
>>> print('name:' + name + ", age: " + age)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
# 用 str()函数将int 转 字符串
>>> print('name:' + name + ", age: " + str(age))
name:hainiu, age: 10
# 用 * 做字符串复制
>>> name * 2
'hainiuhainiu'
● 字符串格式化
格式化方式1:
>>> name = "hainiu"
>>> age = 10
>>> height = 188.001
# 一个字符串占位符
>>> 'name:%s' % name
'name:hainiu'
# 在一个字符串内的占位符多于1个,需要用()
>>> 'name:%s, age:%d' % (name, age)
'name:hainiu, age:10'
>>> 'height:%f' % height
'height:188.001000'
>>> 'height:%.2f' % height
'height:188.00'
>>> 'name:%s, age:%d, heigth:%.2f' % (name, age, height)
'name:hainiu, age:10, heigth:188.00'
其中:
在一个字符串内的占位符多于1个,需要用()
占位符: %s:字符串占位符
%d:int占位符
%f:浮点型占位符
%.2f:保留两位小数浮点数
格式化方式2:
方式2 f-string 是python3.6以后才有的,主要是用f 和 {} 配合实现变量替换,此种方式不用明确指定变量类型
>>> name = "hainiu"
>>> age = 10
>>> height = 188.001
>>> f'name:{name}'
'name:hainiu'
>>> f'name:{name}, age:{age}'
'name:hainiu, age:10'
>>> print(f'name:{name}, age:{age}')
name:hainiu, age:10
>>> f'height:{height}'
'height:188.001'
# 格式化保留2位小数的字符串
>>> f'height:{height:.2f}'
'height:188.00'
>>> f'name:{name}, age:{age}, height{height:.2f}'
'name:hainiu, age:10, height188.00'
● Unicode字符串
在Python2中,字符串有两种类型:str 和 unicode。str 是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。
在Python3中,字符串只有一种类型:str, str 默认就是Unicode字符串,不需要加u。
● 字符串是不可变的
为了提高内存利用效率对于一些简单的对象,如一些数值较小的int对象,字符串对象等,python采取重用对象内存的办法,类似于java的常量池。
id 是查看内存分配情况,通过id可以查询变量是否是在同一内存。
也可以用 is , 比如 a is b 来判断a 和 b 是否在同一内存地址。
java int类型范围:[-128,127]
范围:在交互式开发环境
python:
数值型:[-5,256]
字符串:字母数字下划线组成
如果在源代码里写就不是这样了
4.1.4 逻辑行与物理行、缩进
物理行是你在编写程序时所看见的。逻辑行是Python 看见的单个语句。
默认地,Python希望每行都只使用一个语句,这样使得代码更加易读。
如果想要在一个物理行中使用多于一个逻辑行,那么你需要使用分号(;)来特别地标明这种用法。分号表示一个逻辑行/语句的结束,但python不建议这么干。
python的缩进代表程序的层次结构,python 不允许随便缩进。
一般用 一个Tab 键 来做一次缩进。
4.2 运算符与表达式
4.2.1 运算符
可以交互地使用解释器来计算例子中给出的表达式,例如,为了测试表达式2 + 3,使用交互式的带提示符的Python解释器:
运算符与它们的用法
运算符大类 | 运算符 | 名称 | 说明 | 例子 |
---|---|---|---|---|
算数运算符 | + | 加 | 两个对象相加 | 3 + 5得到8。'a' + 'b'得到'ab'。 |
- | 减 | 得到负数或是一个数减去另一个数 | -5.2得到一个负数 50 - 24得到26。 | |
* | 乘 | 两个数相乘或是返回一个被重复若干次的字符串 | 2 3得到6。 'la' 3得到'lalala'。 | |
** | 幂 | 返回x的y次幂 | 3 * 4得到81(即3 3 3 3) | |
/ | 除 | x除以y,返回float类型 | 3 / 2 得到 1.5 | |
// | 取整除 | 返回商的整数部分,返回int | 3 / 2 得到 1 | |
% | 取模 | 返回除法的余数 | 8 % 3 得到 2 | |
位运算 | << | 左移 | 把一个数的比特向左移一定数目 | 2 << 2得到8 |
>> | 右移 | 把一个数的比特向右移一定数目 | 11 >> 1得到5 | |
& | 按位与 | 数的按位与 | 5 & 3得到1 | |
| | 按位或 | 数的按位或 | 5 | 3得到7 | |
^ | 按位异或 | 数的按位异或 | 5 ^ 3得到6 | |
~ | 按位翻转 | x的按位翻转是-(x+1) | ~5得到-6 | |
比较运算符 | < | 小于 | 返回x是否小于y。 | 5 < 3返回 False 3 < 5返回 True |
> | 大于 | 返回x是否大于y | 5 > 3返回True | |
<= | 小于等于 | 返回x是否小于等于y | 3 <= 5返回True | |
>= | 大于等于 | 返回x是否大于等于y | 5 >=3返回True | |
== | 等于 | 比较对象是否相等 | 5 == 5返回True | |
!= | 不等于 | 比较两个对象是否不相等 | 5 != 3返回True | |
逻辑运算符 | not | 布尔“非” | 如果x为True,返回False。如果x为False,它返回True。 | x = True; not y返回False。 |
and | 布尔“与” | 如果x为False,x and y返回False | x = False; y = True; x and y返回False。 | |
or | 布尔“或” | 如果x是True,x or y返回True | x = True; y = False; x or y返回True。 | |
赋值运算 | = | 赋值 | x = 1 | |
+= | 加法赋值 | x += 1 等效于 x = x + 1 | ||
-= | 减法赋值 | x -= 1 等效于 x = x - 1 | ||
*= | 乘法赋值 | x = 2 等效于 x = x 2 | ||
/= | 除法赋值 | x /= 2 等效于 x = x / 2 | ||
%= | 取模赋值 | x %= 2 等效于 x = x % 2 | ||
**= | 密赋值 | x *= 2 等效于 x = x *\ 2 | ||
//= | 取整除赋值 | x //= 2 等效于 x = x // 2 |
4.2.2 运算符优先级
Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合)。这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算在上部的运算符。使用圆括号来分组运算符和操作数,以便能够明确地指出运算的先后顺序,使程序尽可能地易读。例如,2 + (3 4)显然比2 + 3 4清晰。与此同时,圆括号也应该正确使用,但也不是什么时候都用(比如2 + (3 + 4))。
运算符优先级,由高到低
在表中列在同一行的运算符具有 相同优先级 。例如,+和-有相同的优先级。
计算顺序
默认地,运算符优先级表决定了哪个运算符在别的运算符之前计算。然而,如果你想要改变它们的计算顺序,你得使用圆括号。例如,你想要在一个表达式中让加法在乘法之前计算,那么你就得写成类似(2 + 3) * 4的样子。
结合规律
运算符通常由左向右结合,即具有相同优先级的运算符按照从左向右的顺序计算。例如,2 +3 + 4被计算成(2 + 3) + 4。一些如赋值运算符那样的运算符是由右向左结合的,即a = b = c被处理为a = (b = c)
4.2.3 表达式
使用表达式
length = 5
breadth = 2
area = length * breadth
print('Area: %d' % area)
print('Perimeter: %d' % (2 * (length + breadth)))
4.3 控制语句
在Python中有三种控制流语句——if、for和while。
4.3.1 if语句
在Python中没有switch语句。你可以使用if..elif..else语句来完成同样的工作。
语法:
if 判断条件1:
执行语句1……
[elif 判断条件2:
执行语句2……
elif 判断条件3:
执行语句3……
else:
执行语句4……]
代码示例 :
number = 23
guess = int(input('猜数 : '))
if guess == number:
print('猜中.')
print("(下次就没那么幸运了)")
elif guess < number:
print('小了')
else:
print('大了')
通过if 实现类似java中的三目运算符的操作
语法:
True的结果 if 条件表达式 else false的结果
示例:
x = 10
y = 15
min = x if x < y else y
print 'min:',min
#-----输出结果-------------------------
min:10
4.3.2 while语句
只要在一个条件为真的情况下,while语句允许你重复执行一块语句。while语句有一个可选的else从句。
可在循环控制语句中使用break和continue,使用方式与java一样。
语法格式:
while 条件表达式:
循环体
[else:
# 当由while的条件表达式判断退出循环的,会执行else从句
执行else从句]
代码示例:
不执行while 语句的else情况:
number = 56
running = True
while running:
guess = int(input('猜数 : '))
if guess == number:
print('猜中.')
print("(下次就没那么幸运了)")
break
elif guess < number:
print('小了')
else:
print('大了')
else:
print('while loop is over')
print('game over')
执行while 语句的else情况:
number = 56
running = True
while running:
guess = int(input('猜数 : '))
if guess == number:
print('猜中.')
print("(下次就没那么幸运了)")
running = False
elif guess < number:
print('小了')
else:
print('大了')
else:
print('while loop is over')
print('game over')
4.3.3 for循环
语法格式:
for 循环变量 in 变量组成的序列:
循环体
[else:
else从句]
其中:
in 后面的序列,可以通过range实现。
range语法:
python2 的语法:
python3的语法:
python3 改进range方法,不显示序列了,现在反回的类似迭代器的对象,占用空间小。
可在循环控制语句中使用break和continue,使用方式与java一样。
代码示例:
# 输出1 到 4 的序列
for i in range(1, 5):
print(i)
else:
print('The for loop is over')
#可在循环控制语句中使用break和continue,使用方式与java一样
# 在range(1,8)中输出偶数并且到6就退出
for i in range(1,8):
if i == 6:
break
if i % 2 != 0:
continue
print(i)
else:
print('The for loop is over')
4.4 函数
4.4.1 定义函数
语法格式:
def 函数名(函数形参1, 形参2, ...):
函数体
其中:
函数体用return返回结果。
代码示例:
定义无参无返回值函数:
#定义无参无返回值函数
def say():
print('Hello World!')
#调用函数
say()
print('----------')
#如果函数有返回值就返回相应的值,如果没有返回值,就返回个None
print(say())
定义有参有返回值函数:
def add(a,b):
# 用return返回结果
return a + b
print(add(1,2))
4.4.2 局部变量
如果是字符串、元组、数值型变量,在函数内修改后,函数外是访问不到的。
如果是列表、字典型变量,在函数内修改后,函数外是可以访问到的
示例代码:
def func(x):
print(f'1==>x={x}')
x = 20
print(f'2==>x={x}')
x = 10
func(x)
print(f'3==>x={x}')
4.4.3 使用global语句
如果你想要为一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是全局的。
我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。
可以使用同一个global语句指定多个全局变量。例如global x, y, z。
你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量)。然而,并不鼓励你这样做,并且你应该尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。
代码示例
def func(y):
# 在函数内定义全局变量x,函数外可访问到
global x
print(f'1==>x={x}')
x = 20
print(f'2==>x={x}')
print(f'1==>y={y}')
y = 200
print(f'2==>y={y}')
x = 10
y = 100
func(y)
print(f'3==>x={x}')
print(f'3==>y={y}')
4.4.4 默认参数值
python函数默认是不能像 java 方法一样重载。
但可以通过默认参数解决。
默认参数是在形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。
只有在形参表末尾的那些参数可以有默认参数值,这样调用传递实参时可以不传。
代码示例1:
def say(name=None):
# 函数体根据传过来的参数实现重载逻辑
if name == None:
print('say hello')
else:
print(f'say {name}')
say('hainiu')
# 由于name是默认参数,调用时可以不传
say()
代码示例2:
# 定义多个默认参数
def func1(name, age=0, sex='boy'):
print(f'name:{name}, age:{age}, sex:{sex}')
func1('hainiu1', 10, 'girl')
func1('hainiu2', 10)
func1('hainiu3')
4.4.5 关键参数
如果在调用时不想按照定义参数的顺序传递,可以用关键参数。
关键参数是用k=v的方式传递,可以不管参数的顺序。
1)由于我们不必担心参数的顺序,使用函数变得更加简单了。
2)假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。
代码示例:
def func1(a, b=0, c=0):
print(f'a:{a}, b:{b}, c:{c}')
func1(1,2,3)
# 调用时可以无关形参列表顺序
func1(c=3,a=1,b=2)
# 默认参数和关键参数搭配使用,可以只传递想要传递的参数,不需要关心形参列表顺序
func1(1, c=3)
4.4.6 return语句
函数如果想返回数据,用return返回。否则返回None。
代码示例:
def max_num(x, y):
if x > y:
return x
else:
return y
print(max_num(2, 3))
4.4.7 DocStrings
Python有一个很奇妙的特性,称为 文档字符串 ,它通常被简称为 docstrings 。DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量使用它。你甚至可以在程序运行的时候,从函数恢复文档字符串!
DocStrings也适用于模块和类
文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第三行开始是详细的描述。
代码示例:
def max_num(x, y):
"""
Return maximum of two numbers.
:param x: num1
:param y: num2
:return: max num
"""
if x > y:
return x
else:
return y
print(max_num(2, 3))
#打印函数max_num的doc
print(max_num.__doc__)
其中:Python文档注释写在定义函数的下面
第一行:函数功能,首行以大写字母开始,句号结尾;
第二行:空行;
第三行以后:函数的属性及返回值
强烈建议在你的函数中使用文档字符串时遵循这个惯例。你可以使用doc(注意双下划线)调用max_num函数的文档字符串属性(属于函数的名称)。请记住Python把 每一样东西 都作为对象,包括这个函数。
如何打印官方给的doc?
4.4.9 匿名函数
python 使用 lambda 来创建匿名函数。
◇ lambda只是一个表达式,函数体比 def 简单很多。
◇ lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
语法:
lambda [arg1 [,arg2,.....argn]]:expression
# lambda 参数列表:return [表达式] 变量
# 由于lambda返回的是函数对象(构建的是一个函数对象),所以需要定义一个变量去接收
示例:
#普通函数
def add(x, y):
return x + y
print(add(1,3))
#匿名函数
add1 = lambda x, y : x + y
print(add1(1,5))
#将匿名函数作为函数的参数传递
def func1(x,y,func2):
return func2(x,y)
# 只要是符合两个参数输入,一个返回值的函数,都可以放
print(func1(1,6,lambda x,y : x + y))
print(func1(1,6,lambda x,y : x * y))
print(func1(1,6,lambda x,y : x - y))
4.5 模块
4.5.1 什么是模块?
模块是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件名必须以.py为扩展名。
模块可以从其他程序导入以便利用它的功能。
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
首先,我们将学习如何使用标准库模块。
4.5.2 使用sys模块
代码示例:
# 引入python环境模块
import sys
# 获取当前环境入参
print(sys.argv)
# 添加python环境path
# 当在linux上运行python脚本时,需要在代码中追加python环境path
sys.path.append(r"C:\Users\My\Desktop\py")
# 获取当前python环境path
for p in sys.path:
print(p)
它如何工作
首先,我们利用import语句输入sys模块。基本上,这句语句告诉Python,我们想要使用这个模块。sys模块包含了与Python解释器和它的环境有关的函数。
当Python执行import sys语句的时候,它在sys.path变量中所列目录中寻找sys.py模块。如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被你使用。注意,初始化过程仅在我们第一次输入模块的时候进行。另外,“sys”是“system”的缩写。
sys模块中的argv变量通过使用点号指明——sys.argv——这种方法的一个优势是这个名称不会与任何在你的程序中使用的argv变量冲突。另外,它也清晰地表明了这个名称是sys模块的一部分。
sys.argv变量是一个字符串的 列表 (列表会在后面的章节详细解释)。特别地,sys.argv包含了命令行参数的列表,即使用命令行传递给你的程序的参数。如果你使用IDE编写运行这些程序,请在菜单里寻找一个指定程序的命令行参数的方法。
这里,当我们执行function_test.py 11 22 33的时候,我们使用python命令运行function_test.py模块,后面跟着的内容被作为参数传递给程序。Python为我们把它存储在sys.argv变量中。
sys.path包含输入模块的目录名列表。我们可以观察到sys.path的第一个字符串是空的——这个空的字符串表示当前目录也是sys.path的一部分,这与PYTHONPATH环境变量是相同的。这意味着你可以直接输入位于当前目录的模块。否则,你得把你的模块放在sys.path所列的目录之一。
1)通过IDE运行
Pycharm 传参
传入 a1 b2 c3
运行结果:
其中:
脚本的名称总是sys.argv列表的第一个参数,其他的是传入的参数。列表,Python从0开始计数,而非从1开始。
2)通过命令行运行
3) 字节编译的.pyc文件
输入一个模块相对来说是一个比较费时的事情,所以Python做了一些技巧,以便使输入模块更加快一些。方法是创建 字节编译的文件 ,这些文件以.pyc作为扩展名。字节编译的文件与Python变换程序的中间状态有关(是否还记得Python如何工作的介绍?)。当你在下次从别的程序输入这个模块的时候,.pyc文件是十分有用的——它会快得多,因为一部分输入模块所需的处理已经完成了。另外,这些字节编译的文件也是与平台无关的。
4.5.3 from...import语句 与 import语句
定义m1.py模块,用于被引入
# -*- encoding: utf-8 -*-
"""
m1.py
Created on 2021/10/6 14:29
Copyright (c) 2021/10/6, 海牛学院版权所有.
@author: 潘牛
"""
name = "hainiu"
def say():
print("say hainiu")
_age = 10
4.5.3.1 from...import语句
# -*- encoding: utf-8 -*-
"""
m2.py
Created on 2021/10/6 14:35
Copyright (c) 2021/10/6, 海牛学院版权所有.
@author: 潘牛
"""
# 从 xx包xx模块 引入 xx成员
from day01.m1 import name, say as say2, _age
print(name)
say2()
print(_age)
from ...import * 不能引入单下划线开头的成员
# from ...import * 不能引入单下划线开头的成员
from day01.m1 import *
print(name)
say()
# 不能引入
# print(_age)
4.5.3.2 import语句
# 引入xx包的xx模块
import day01.m1
day01.m1.name
day01.m1._age
# 也可以起别名
import day01.m1 as dm1
dm1.name
dm1._age
4.5.4 模块的__name__
每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。这在一个场合特别有用——就如前面所提到的,当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们该怎么做呢?这可以通过模块的name属性完成。
m1.py
# -*- encoding: utf-8 -*-
"""
m1.py
Created on 2021/10/6 14:29
Copyright (c) 2021/10/6, 海牛学院版权所有.
@author: 潘牛
"""
name = "hainiu"
def say():
print("say hainiu")
_age = 10
# 当前脚本运行:__name__: __main__
# m2.py 引入m1模块时,__name__: day01.m1
print(f'__name__:{__name__}')
# 用__name__ == '__main__',来做单元测试的入口
if __name__ == '__main__':
print(name)
say()
print(_age)
当 m1 模块自己执行时,打印的 name 是 “main”。
当 m1 模块别其他模块引用时,打印的 name 是 “day01.m1”。
# -*- encoding: utf-8 -*-
"""
m2.py
Created on 2021/10/6 14:35
Copyright (c) 2021/10/6, 海牛学院版权所有.
@author: 潘牛
"""
from day01.m1 import name
print(name)
当想对 m1 模块做测试时,需要加 if name == 'main': 这样的代码,不会影响其他模块引用的同时还不会执行这块代码。
4.6 Python获取帮助的三种方式
4.6.1 doc
参考:DocStrings
4.6.2 dir() 函数
使用dir函数dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;
带参数时,返回参数的属性、方法列表。如果参数包含方法dir(),该方法将被调用。
如果参数不包含dir(),该方法将最大限度地收集参数信息。
语法:
dir([object])
参数说明:
object:对象、变量、类型。
a = 5 # create a new variable 'a
dir()
del a # delete/remove a name
dir()
4.6.3 help()函数
help() 函数用于查看函数或模块用途的详细说明。
语法:
help([object])
参数说明:
object : 对象;
a = 1
help(a)
help(sys)