一、Python 简介
Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python 由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。像 Perl 语言一样, Python 源代码同样遵循 GPL(GNU General Public License) 协议。
官方宣布,2020 年 1 月 1 日, 停止 Python 2 的更新。Python 2.7 被确定为最后一个 Python 2.x 版本。
Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
- Python 是一种解释型语言:这意味着开发过程中没有了编译这个环节。类似于 PHP 和 Perl 语言。
- Python 是交互式语言:这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。
- Python 是面向对象语言: 这意味着 Python 支持面向对象的风格或代码封装在对象的编程技术。
二、Python 程序开发
2.1、python 的工程结构
在开发过程中,不会将所有的代码放到一个文件中,而是将功能类似的类或函数放到一起,这样代码结构清晰,管理方便。在 Python 中使用模块来管理代码,事实上一个 Python 文件也就是一个.py 结尾的文件就是一个模块。在模块中可以定义函数、类和变量,甚至可以包含可执行的代码。
2.2、导入模块
Python 的模块分为内置模块和第三方模块。内置模块只要安装了 Python 就可以使用,要使用第三方的模块则需要进行安装。本书使用的 Anaconda 能够非常便捷的管理安装第三方模块。当要在自己的代码文件中调用其他模块的代码时,首先要确保该模块已经安装,然后可以使用 import 关键字导入模块。模块导入后就可以调用模块中的类或者函数了。
import random
#生成一个 0~99 的整数,包含 0 和 99
random_int = random.randint(0,99)
print("生成的随机数是:",random_int)
使用 import 关键字导入某模块后,就能以模块名.方法()
的方式调用模块中的方法了。这种调用模块中的方法可以实现调用模块中所有类或方法的目的,但是调用时需要使用模块名作引用才能调用指定的方法。Python 的语法允许有针对性的导入模块中的某一部分,这样在调用方法是会显得更加简洁,导入的语法如下。
导入模块语法:
from 模块名 import 方法名或类名
示例:
from random import randint
blue_balls = []
while len(blue_balls) != 6:
blue_ball = randint(1,33)
if blue_ball not in blue_balls:
blue_balls.append(blue_ball)
red_ball = randint(1,16)
blue_balls.sort()
print("篮球:",blue_balls)
print("红球:",red_ball)
在导入模块时 Python 还允许给模块起一个别名。因为有的模块名字比较长,在代码中使用的次数还比较多,每次都写模块的全名会使代码变得臃肿,不利于阅读,此时就可以使用取别名的方式来解决这个问题。
模块别名语法:
#给模块取别名
import 模块名 as 模块的别名
#给模块中的方法或类取别名
from 模块名 import 模块中的方法或类 as 别名
- 假如导入的内容使用 as 起了别名,那么原名就不可以使用了,只能使用别名进行调用。
- 在代码中导入模块要根据实际情况选择直接导入整个模块,还是选择性的导入某一方法或类,以及是否需要给导入的内容起一个别名。恰当的选择导入的方式能够提高代码的可读性,减少冗余的代码量。但是不管哪种导入方式最后在使用时效果都是一样的,不会因为选择了哪种导入方式引起程序运行错误。
示例:
from random import randint as ri
blue_balls = []
while len(blue_balls) != 6:
blue_ball = ri(1,33)
if blue_ball not in blue_balls:
blue_balls.append(blue_ball)
red_ball = ri(1,16)
blue_balls.sort()
print("篮球:",blue_balls)
print("红球:",red_ball)
2.3、创建模块
在 Python 中,一个.py 文件就是一个模块,文件名就是这个模块的名字。如果调用者和被调用者处于同一文件夹下,那么使用关键字 import 加文件名即可实现导入模块。
为了更好的组织模块,通常会将多个功能相近或有关联的模块放在一个包中。包就是 Python 模块文件所在的目录,文件夹名就是包名。再使用包时,文件夹下必须存在一个__init__.py
文件(文件内容可以为空),__init__.py
用于标识当前文件夹是一个包,如果缺少了这个文件,文件夹外的文件是无法导入文件
中的模块的。其他文件夹下的文件在导入包中模块时的语法如下。
语法
import 包名.模块名
三、变量和数据类型
3.1、变量
Python 中定义变量不需要指定变量类型。变量的类型是根据赋值动态改变的。因此在 Python 中是不能像 Java 一样只声明变量而不给变量赋值的。
a=1
b=3
c="abcd"
d=1.2596
print(a,",",b,",",c,",",d)
3.2、列表/元祖
- Python 中的列表与 Java 不同,列表中的数据可以是任何类型的。
- 注意列表的索引可以为负。
- range 类型主要用于 for 循环遍历。
a=[]
b=[1,2,3,4]
print(a,b)
3.3、Python 直接赋值、浅拷贝和深度拷贝
【1】b = a: 赋值引用,a 和 b 都指向同一个对象
【2】b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是
指向统一对象(是引用)
【3】b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对
象,两者是完全独立的。
四、函数
Python中函数是对象
- 函数可以被引用,即函数可以赋值给一个变量
- 函数可以当做参数传递
- 函数可以作返回值
- 函数可以嵌套
4.1、内置函数
无需导包即可使用的函数,不同版本的 Python 内置函数可能略有不同
常用内置函数:
函数 | 作用 |
---|---|
type() | 返回变量数据类型 |
dir() | 如果没有实参,则返回当前本地作用域中的名称列表。如果有实参,它会尝试返回该对象的有效属性列表 |
input() | 输入 |
print() | 打印输出 |
id() | 返回变量的物理地址 |
abs() | 返回一个数的绝对值 |
max() | 返回迭代器中最大的元素 |
min() | 返回迭代器中最小的元素 |
4.2、自定义函数
语法:
def func_name(参数列表):
函数体
[return/yield 函数返回值]
Python函数的特点
- 函数参数类型多样
- 允许嵌套函数
- 无需声明函数返回值类型
- yield 可以作为函数返回值的关键字
- 函数能够被赋值给变量
4.2.1、函数参数
函数参数重有一定难度的使用方式是包裹位置参数和包裹关键字参数。这两种参数都是不定长参数。在自己的开发中这两种参数的使用场景不多,但是在各种 Python 第三方库中,包裹关键字参数的出现频率很高。
在使用多种类型的参数定义函数时,一定要注意各种类型参数的顺序:
- 无参函数
- 位置参数
- 默认值参数
- 包裹位置参数
- 包裹关键字参数
4.2.2、无参函数
没有参数
def show_log():
print('I am a log')
show_log()
4.2.3、位置参数
传入的参数与定义的参数一一对应
def func_name(arg1,arg2,arg3):
print(arg1,arg2,arg3)
func_name("abc","cdf","gh")
4.2.4、关键字参数
直接通过等号传递参数
def func_name(arg1,arg2,arg3):
print(arg1,arg2,arg3)
func_name(arg1="val1",arg3="val3",arg2="val2")
4.2.5、默认值参数
-
定义函数时,设置参数的默认值
-
调用函数时,可以指定通过位置或者关键字指定参数的值,如果不指定,参数为默认值
def func_name(arg1="val1",arg2="val2",arg3="val3"):
print(arg1,arg2,arg3)
func_name()
4.2.6、不定长参数
参数的个数不确定,可适应更加复杂情况
包裹(packing)位置参数
- 参数表示为
*args
- 注意传入数据类型相同
- 调用函数时,参数自动会组织成一个元组传入
- 传入的位置参数与组织成的元组索引位置一致
def func2( *t ):
print(t)
func2()
func2(1,2,3)
func2(1,2,3,4,5)
包裹(packing)关键字参数
- 参数表示为
**kwargs
- 调用函数时,参数自动会组织成一个字典传入
- 传入的位置参数与组织成的字典的键值对一致
def func3( **d ):
print(d)
func3()
func3(a=1, b=2, c=3)
4.3、嵌套函数
-
在函数内部定义新的函数
-
内部函数不能被外部直接调用
-
函数可以被当做变量赋值,因为本质函数是一个对象
def func6() :
def nestedFunc() :
print('Hi')
return nestedFunc
x=func6()
x()
4.4、装饰器
Python 中的装饰器是 Python 万物皆对象的一种体现,实质是在函数中定义函数、从函数中返回函数、将函数作为参数传给另一个函数。
- 修改其他函数的功能的函数
- 使函数更加简洁
#定义装饰器
def my_decorator(some_func):
def wrapper(*args):
print("I am watching you!")
some_func(*args)
print("You are called.")
return wrapper
#使用装饰器
@my_decorator
def add(x, y):
print(x,'+',y,'=',x+y)
#函数调用
add(5,6)
对上面的例子做一些解释
- my_decorator 的参数是一个函数,也就是被装饰的函数 add(x,y)
- 在函数 my_decorator 中定义一个函数 wrapper,这个函数的参数在本例中就是 add(5,6)中传进来的参数。这个参数你是否要继续传给 some_func 使用都可以由你自己来决定,这就是装饰器的强大之处体现了
- my_decorator 的返回值就是也是一个函数,也就是 wrapper
- 在使用装饰器使需要在使用@符号
4.5、全局变量
全局变量在整个模块中可见,修改全局变量时,要先使用global关键字声明变量
globals() 函数:返回所有定义在该模块中的全局变量
msg = 'created in module'
def outer_1() :
def inner() :
global msg
msg =520
print("print in inner",msg)
inner()
outer_1()
print(msg)
4.6、局部变量
定义在函数中的变量,局部变量仅在定义的函数中可见
locals()函数:返回所有定义在函数中的局部变量
def outer_1() :
msg = 'created in outer'
def inner() :
print(msg)
inner()
outer_1()
自由变量:在函数中使用,但未定义在该函数中的非全局变量
nonlocal关键字:修改自由变量时,要先使用nonlocal关键字声明变量
def outer():
msg = 'created in outer'
def inner() :
nonlocal msg
msg = 'changed in inner'
inner()
print(msg)
outer()
4.7、函数的返回值
函数无需声明返回值类型,在函数没有返回值时,函数默认返回 None,return关键字用于返回返回值
yield关键字
当函数使用yield关键字时,函数变为生成器
- 生成器是Python中的一种可迭代对象
- 能够使用for循环遍历
- 生成器每次只被读取一次
- 生成器有内置方法__next()__,调用后返回下一个元素
yield不会终止程序,返回值之后程序继续运行
五、表达式
5.1、生成器表达式
(x**3 for x in range(10))
生成器示例:
求斜边小n的勾股数组合
def list_pythagorean_triples(n) :
for c in range(n):
for a in range(1, c):
for b in range(1, c):
if a*a+b*b==c*c:
yield (a,b,c)
#使用循环迭代生成器
for i in list_pythagorean_triples(35):
print(i)
#使用next()方法从生成器中取值
g = list_pythagorean_triples(100)
next(g)
#构造生成器的结果列表
g = list_pythagorean_triples(100)
list(g)
生成器的使用方法
- for循环迭代生成器
- next()函数从生成器中取值
- 构造生成器的结果列表
5.2、列表生成式
[x**3 for x in range(10)]
5.3、lambda表达式
lambda表达式是一个匿名的函数
语法
lambda param1, param2, … : expression
示例:
# return results of +, -, *, //, % in a list
a=lambda x,y: [x+y, x-y, x*y, x//y, x%y]
# return max, min, sum in a tuple
b=lambda *n: (max(n), min(n), sum(n))
# sum 1 to n
c=lambda n: sum(range(1, n+1))
print(a(2,6))
print(b(2,5,6,1,4,3,8))
print(c(6))
六、正则表达式
6.1、正则方法
Python正则表达式模块:re模块
import re
常用方法
表达式 | 说明 |
---|---|
compile() | 用于编译正则表达式,生成一个正则表达式( Pattern )对象 |
match() | 查看字符串的开头是否符合匹配模式,如果匹配失败,返回none |
search() | 扫描整个字符串并返回第一个成功的匹配 |
findall() | 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表 |
sub() | 替换字符串中的匹配项 |
6.2、正则匹配
符号 | 说明 |
---|---|
逐字匹配 | |
| |
或 |
. |
除换行符外匹配任意字符 |
[...] |
匹配任意一组字符中的一个 |
[^...] |
匹配不在[]中的字符 |
\d |
匹配任意数字 |
\D |
匹配任意非数字 |
\w |
匹配字母数字及下划线 |
\W |
匹配非字母数字及下划线 |
\s |
匹配任意空白字符 |
\S |
匹配任意非空字符 |
^ |
匹配字符串的开头 |
$ |
匹配字符串的末尾 |
\b |
匹配一个单词边界 |
\B |
匹配非单词边界 |
re* |
匹配0个或多个的表达式 |
re+ |
匹配1个或多个的表达式 |
re? |
匹配0个或1个表达式 |
re{n} |
匹配n个前面的表达式 |
re{n, m} |
匹配n到m次前面的表达式 |
?= |
前向肯定界定符 |
?! |
前向否定界定符 |
?<= |
向后肯定界定符 |
?<! |
向后否定界定符 |
6.3、Python正则使用
Python 正则详情请看:Python 正则表达式
七、Python(余)
待续…