Python
2022/5/24 1:19:51
本文主要是介绍Python,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- anaconda的环境设置命令
- 赋值
- 基本数据类型
- 整型和浮点型
- 字符串
- 布尔值
- 逻辑运算符
- 分支与循环语句
- if条件语句
- for循环语句
- while语句
- 序列
- 序列相关的内置函数
- 列表
- 元组
- 封包和解包(元组,列表)
- 字典
- 集合
- 模块和包
- 导入模块
- 使用主入口__main__的意义
- 导入包
- __init__.py的作用
- 导入模块
- 脚本运行
- 帮助系统
- 为函数编写帮助
- 函数
- 主函数
- 函数的定义
- 顺序参数与关键字参数
- 变量的作用域
- 形参和实参
- 默认参数
- 参数收集
- 关键字参数收集
- 逆向参数收集
- 参数传递机制
- return返回值
- Lambda表达式
- 异常处理
- 异常处理的结构
- 触发异常
- 内置电池函数
- 基本函数
- 文件
- 面向对象
- 创建类和实例
- 面向对象编程
- 封装
- 实例方法、类方法、静态方法
- 动态的添加属性和方法
- 动态添加属性
- 动态添加方法
- 继承
- super()函数调用的方法
- 对于属性的继承
- 类变量
- 常用模块
- re模块
- 正则表达式预定义字符
- 正则表达式特殊字符
- 正则表达式合理字符
- 匹配方法 match, search
- 查找方法 findall, finditer, fullmatch
- re模块
- 工程目录
anaconda的环境设置命令
anaconda 包含了conda和pip两个包管理工具。
conda -V / conda --version 查看conda的版本。
conda update anaconda 升级anaconda的版本。
conda update conda 升级conda包管理器的版本
conda update pip 升级pip包管理器的版本。
conda env list 查看系统中虚拟环境。
(base) leo@leo-Surface-Pro:~$ conda env list # conda environments: base * /home/leo/anaconda3
conda activate env_name 切换虚拟环境
conda deactivate 退出当前虚拟环境,进入base。
conda create -n env_name 创建虚拟环境。
conda create -n env_name -c 源env_name 从其他环境复制一份新的虚拟环境。
conda remove -n env_name --all 删除虚拟环境
conda(pip) install -n env_name module_name 安装模块
conda install -n demo selenium conda install python=3.9.4
conda remove -n 环境名 模块名 删除conda安装的模块
pip3 uninstall -n 环境名 模块名 删除pip删除的模块模块
conda list -n 环境名 显示指定环境下安装的模块。
配置Pycharm使用Anaconda的环境
创建新的项目,使用已经配置的虚拟环境。
赋值
x, y, z = 1,[1,2,3], 'Fidelio'
x = 'micros' , 'Fidelio' ==> ('micros' , 'Fidelio')
a, b = b, a 值互换
m = n = 'Fidelio' 链式赋值
id(对象) 显示对象的内存地址。
a is b 判断a 和 b 是不是一个对象。
基本数据类型
Python的每个对象在内存中都有自己的地址,使用 id(对象) 可以获得内存地址。
type(对象) 可以查看对象的类型。
a = 'www.163.com' id(a) 4592242544 type(a) <class 'str'>
对象有类型,变量无类型。 变量只是一个标签,贴到不同的对象上。
整型和浮点型
整型 int表示, 浮点型 float表示。
浮点数与整型运算,得到的是浮点型。
Python解决了整型溢出的问题。
浮点数可以使用科学记数法表示,2e3表示2000.0, 浮点数。
浮点数会溢出。
// 取得两个数的整数商,不是四舍五入,而是直接去整。
误差问题
100.0 / 3 得到的结果是33.333333333333336。
要获得准确的结算结果,需要使用decimal模块的Decimal类型。
使用内置的round(数值,保留小数位)来进行四舍五入计算。
#decimal.Decimal演示 import decimal a = decimal.Decimal(100) b = decimal.Decimal(3) a / b Decimal('33.33333333333333333333333333') #round()的演示 round(a/b,2) Decimal('33.33')
字符串
字符串可以使用单引号或者双引号,结果都是一样的。
转义
\ 是转义字符。
- \n换行
- \b 退格
- \000 空白,其后面的内容不现实。
- \f 换页
r'字符串' 代表字符串中的字符就是原始字符,不包含特殊含义。
print('Micros\nFidelio') Micros Fidelio print(r'Micros\nFidelio') Micros\nFidelio
字符串切片
字符串是一个序列,可以使用序列的方法进行操作。
- 通过索引可以访问字符串的字符。
- 切片 str[开始索引:结束索引] 包头不包尾。
- len(str) 获得字符串长度。
- + 连接两个序列。
- * 重复序列的元素,生成新序列。
- in 判断元素是否在序列中
- max(str) , min(str) 虽然最大值元素和最小值元素。
str[0:3] 'abc' str[:3] 'abc' str[3:] 'de' str[-3:-1] 'cd' str[::2] 'ace' max(str) 'e' min(str) 'a' 'a' in str True str * 3 'abcdeabcdeabcde'
字符与编码转换
ord(字符) 获得字符对应的数字编码。 chr(数字) 获得数字对应的字符。
字符串的格式化
- "{0:15}".format(str) 使用str替换占位符,15个字符长度,靠左对齐。
- "{0:>15}".format(str) 使用str替换占位符,15个字符长度,靠右对齐。
- "{0:^15}".format(str) 使用str替换占位符,15个字符长度,居中对齐。
- "{0:>15.2}".format(str) 使用str的前两个字符替换占位符,15个字符长度,靠右对齐。
- "{0:^10d}".format(int) 使用int替换占位符,10个长度,居中对齐。
- "{0:010d}".format(int) 使用int替换占位符,10个长度,靠右对齐,不足补0。
- "{0:010.2f}".format(float) 使用float替换占位符,10个长度,四舍五入保留两位小数,不足补0。
- "{Key1} and {Key2}".format(Key1 = value, Key2=value)
- f"{变量名} 其他内容 {变量名}"
'I love {0:^10}'.format('fidelio') >>'I love fidelio ' 'I love {0:^10.2}'.format('fidelio') >>'I love fi ' 'My weight is {0:^10.2f} kg'.format(87.567) >>'My weight is 87.57 kg' 'My height is {0:^10d} cm'.format(180) >>'My height is 180 cm' 'My height is {0:010d} cm'.format(180) >>'My height is 0000000180 cm' 'I like {lang} and {name}'.format(lang = 'Python', name = 'Leo') >>'I like Python and Leo'
字符串检查方法
- str.isalnum(): 是否只包含字母和数字。
- str.isdigit():是否只包含数字。
- str.isspace(): 是否只有空白, \n\t都会是True。
- str.istitle():是否每个单词都是第一个字母大写。
- str.islower():是否都是小写。
- str.isupper(): 是否都是大写。
- str.startswith(str1):字符串是否是str1开头
- str.endswith(str1):字符串是否是str1结尾
字符串修改
- str.split(str1): 使用str1分割字符串,返回一个字符串列表。默认参数是空格。
- str.lstrip():去掉字符串左边的空白。
- str.rstrip(): 去掉字符串右边的空白。
- str.strip():去掉字符串两边的空白。
- str.upper():全部转为大写
- str.lower():全部转为小写
- str.capitalize(): 首字母大写
- str.title():每个单词的第一个字母大写
- str.join(序列):返回 序列元素1+'str'+序列元素2+'str'. split的逆操作。
布尔值
True / False
直接得到真值: 数字1, 任何非空的东西,例如:非空字符串,非空序列。
直接得到假值:数字0, 任何空的东西,例如:空字符串,空序列,None。
逻辑运算符
and
or
not
分支与循环语句
if条件语句
if 条件:
语句块
elif 条件 :
语句块
else :
语句块
三目运算符:
A = X if 条件 else Y 条件为真,A=X,否则A=Y。
pass 站位语句,什么也不做。if语句后如果什么也不写会抛出异常,可以使用pass占位。
for循环语句
- for i in range(10):
语句块 i = 0 ~9
-
for element in 集合 :
语句块
-
for 条件:
语句块
else:
语句块
for 运行完以后,else语句块执行。
for被break以后,else语句块不会执行。
- 列表推导式 list = [ i for i in range(10) ]
while语句
while 条件 :
语句块
else :
语句块(当while条件不在成立时)
while条件为True时, else语句块不会执行。当While条件为False时,else语句块执行。
break 跳出循环体
continue 从continue所在位置调到循环语句块的最后一行(不执行最后一行)
序列
序列相关的内置函数
len(序列) 序列元素的个数,或者字符串的字符个数。
max(序列) 序列的最大元素。
min(序列) 序列的最小元素。
列表
list = [元素,元素]
list = list(元组) 将元组转为列表
list = list[: :-1]反转元素。
list.count(元素) 元素出现的次数。
list.index(元素) 元素出现的位置。找不到返回ValueError异常。
list.remove(元素) 从列表中删除元素,找不到元素返回ValueError异常。
list.pop(i) 删除索引为i的元素,并返回元素。不加参数默认删除最后一个元素。
del 列表[索引] 删除列表指定索引的元素。
list.reverse() 反转列表中的元素。
list.sort() 将列表的元素进行升序排序。list.sort(reverse = True) 进行降序。list.sort(key=len) 以元素的长度排序。
list.append(元素) 将元素添加到list。
list.insert(位置, 元素) 将元素插入到位置。
reversed(列表) 返回一个反向排序的元组。
str.join(列表) 返回一个str连接列表元素的字符串。
列表支持加法和乘法。
元组
tuple = (元素, 元素), 只有一个元素是,使用 tuple = (元素, )
来创建元组。
tuple = tuple(list) 将列表转为元组
tuple.count(元素) 元素出现的次数。
tuple.index(元素)
封包和解包(元组,列表)
封包: 将多个值赋值给一个变量,会产生一个元组。
解包:将一个元组或者列表的元素赋值给多个变量。
#封包 >>> names = 'leo', 'kevin', 'winston' >>> names -> ('leo', 'kevin', 'winston') #解包 >>> name1, name2, name3 = names >>> print(name1, name2, name3, sep='\n') leo kevin winston
字典
字典的key一定是不可改变的类型,比如字符串常量,数值常量,布尔类型,元组。
dict() 转换元组或者列表为字典。
a= (['name', 'leo'], ['age', 18], ['gender', 'male']) b = dict(a) b {'name': 'leo', 'age': 18, 'gender': 'male'}
dict.copy() 产生另外一个字典对象。
如果dict中的元素有引用型,需要使用copy模块的deepcopy命令来产生一个完全不同的字典。
import copy a = {'name': ['leo','kevin']} b = copy.deepcopy(a)
dict[键] 或者dict.get(键) 区别是get方法找不到key的时候也不返回异常。
dict.get(key , [ default ] ) 找到key,返回value,找不到,返回default(可选参数,默认为None)。
dict[key] = value 来设置键值对,缺点是如果存在键值对,会被覆盖掉。
dict.setdefault(key, [default] ) ,如果能找到key, 则返回value。 找不到key,就设置一个dict[key] = default , 并返回default。
dict.update(dict) 融合两个字典的键值对。如果作为参数的字典的key在当前字典存在,则更新value。
del dict[key] 删除键值对,找不到返回KeyError 异常。
dict.pop(key , [default]) 删除一个键值对,返回value,找不到默认返回异常。如果设置了default,返回default。
dict.popitem() 随机删除一个键值对,并用元组的形式返回删除的键值对。
dict.clear() 清除字典的所有键值对。被清空的字典为{ } , 仍然存在内存中。 del(dict) 就把字典从内存中销毁。
dict = {'name':'leo', 'age':18, 'gender':'male'}
dict.keys() 得到所有的key,以列表返回。['name', 'age', 'gender']
dict.values() 得到所有的value,以列表返回。['leo', 18, 'male']
dict.items() 得到所有的键值对,每个键值对放在一个元组中,所有的元组放在一个列表中。
[('name', 'leo'), ('age', 18), ('gender', 'male')]
集合
使用set(序列)可以创建可变集合。
set1 = set(['Leo' , 'Fidelio']) {'Fidelio', 'Leo'} list1 = list(set1) #将集合转为列表 或者用tuple转元组。
集合没有索引,也没有顺序,不属于序列。
集合中不能有重复的数据,重复数据会自动删除。
集合中不能添加可变类型的数据,例如列表不能添加到集合中。
set.add(元素) 向集合中添加元素。
set.update(set1) 将set1的元素添加到集合中。
set.pop() 随机删除集合的元素,不能有参数指定。空集合删除元素返回异常。
set.remove(元素) 删除指定的元素。删除不存在的元素会返回异常。
set.discard(元素) 删除指定的元素。元素不存在也不会返回异常。
set.clear() 清除集合的所有元素。
可以用集合set() 方法消除重复项。
list1 = [1,2,3,4,5,1,1,2,3,1,4] list1 = list(set(list1)) print(list1) -> [1, 2, 3, 4, 5]
元素 in 集合 判断元素是否存在于集合。
集合1 == 集合2 判断两个集合的元素是否相同。
集合1 < 集合2 判断集合1是不是集合2的子集。a.issubset(b)
集合1 > 集合2 判断集合1是不是集合2的超集。a.issuperset(b)
集合1 | 集合2 返回两个集合的并集。 a = a.union(b)
集合1 & 集合2 返回两个集合的交集。a = a.intersection(b) intersection_update 直接更新a
集合1 - 集合2 返回集合1相对于集合2的差集。a.difference(b) difference_update会直接更新a。
集合1 ^ 集合2 返回集合1和集合2的对称差集。a.symmetric_difference(b)
使用frozenset() 创建不可变集合。
dir(frozenset) 查看可用的命令。
模块和包
使用模块的优点:
- 提供代码可重用性。
- 提供独立的命名空间。
导入模块
import 模块名
import 模块名, 模块名, 模块名
from 模块名 import 函数名 导入模块下的某个函数。
from 模块名 import 函数名 as 别名 导入模块下的某个函数,并给一个别名。
from 模块名 import * 导入模块下的所有函数,不推荐。
使用主入口__main__的意义
当import的时候,会立即运行一遍导入的模块的代码。
如果模块有主入口的main函数语句,只有当前py文件被当成程序执行的时候才执行。作为模块被导入时,不会执行main函数的语句。
当模块没有包含在sys.path中,是无法导入的。
两个方法:
-
将模块创建在这个目录: '/Users/leo/opt/anaconda3/lib/python3.9/site-packages'
-
将需要使用的目录添加到sys.path 环境变量。
import sys new_path = '/home/leo/PycharmProjects/leo1/venv/fid/fid' sys.path.append(new_path) import my_first_module my_first_module.say_hello()
导入包
使用. 进入包的目录,找到对应的模块。
import 包路径
import 包路径.包路径
from 包路径 import 模块名
from asyncio.events(包.模块) import Handle(类)
__init__.py的作用
导入包的时候,就会读取包目录下的__init__.py文件。
__init__.py的作用是:
- 编写一些让导入者可以看到的信息。
- 提供可以调用的信息,比如: 类、方法、函数、变量等。
- 把下级成员的模块导入到顶层模块,然后通过顶层模块直接调用。
Fidelio包的__init__.py中定义了函数. def intro(): print('Hello, I will facilitate the opera manipulation....') 导入Fidelio包的时候,init.py自动运行,函数可以使用. import Fidelio Fidelio.intro() -> Hello, I will facilitate the opera manipulation....
Fidelio包中的init.py,将其包含的模块的方法导入Fidelio包的环境。 from Fidelio.mod1 import fun1 from Fidelio.mod2 import fun2 from Fidelio.Opera.mod3 import fun3 写程序的时候,导入Fidelio包就可以通过Fidelio.fun1()去调用了。 Fidelio.fun1()
脚本运行
脚本开头的两句话,第一句指明python的位置,第二句指明使用utf8编码,避免中文乱码。
#!/usr/bin/env python #coding:utf-8
python运行的时候,会将py文件编译为pyc文件。如果没有修改py文件,那么执行这个程序的时候,会直接运行之前生成的pyc文件,这样可以提升执行速度。
帮助系统
-
单行注释 #
-
多行注释
```
多行注释
\```
查看函数的功能,可以使用 help(函数) 来查看。
help(id) 输出如下: Help on built-in function id in module builtins: id(obj, /) Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects. (CPython uses the object's memory address.)
可以使用函数或者对象的__doc__属性来查看帮助文档。
print(print.__doc__) output: print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline.
为函数编写帮助
使用三引号将帮助信息包含在函数定义的下一行。
def calc_score(*scores): """ 本函数用来计算总成绩。 :param scores: 可以填写多个成绩。 :return: 返回总成绩 """ total = 0 for i in scores: total += i return total
函数
函数可以封装代码,达到代码复用的目的; 创建一个新的命名空间。
主函数
main函数时程序的主入口。作为模块被调用的时候,主函数中的语句避免了脚本运行。
#pycharm中输入main()即可 #main函数的上面定义函数和类。 if __name__ == '__main__': 代码...
函数的定义
def 函数名(参数...): 语句... 语句...
顺序参数与关键字参数
顺序参数按照型参定义的顺序传递参数,顺序不能乱,参数不能少。
使用函数名 = 值的形式传递的参数。顺序可以乱,参数不能少。
def func(var1, var2): print(var1, var2) func(var2 = 'Zhang' , var1 = 'Leo')
变量的作用域
作用域定义了变量能在多大的范围内被访问。
- 全局变量:直接在内存中定义的单独变量。全局变量可以在任何地方访问。
- 局部变量: 在函数中定义的变量叫做局部变量。局部变量只能在定义的函数中,或者函数的函数中被访问。
def demo(): var = 20 #局部变量 #函数中使用global var可以访问全局变量。不实用global,则会创建一个新的局部变量。 if __name__ == '__main__': var = 10 #全局变量
形参和实参
定义函数的参数列表叫做形参。
调用函数传入的参数列表叫做实参。
def demo(var): #定义函数的规定的参数是形参 pass demo(123) #调用函数时实际传入的参数是实参。
默认参数
指定默认值的参数的值,调用的时候可以不传递这个参数。
默认值参数应该放在型参列表的最后。
为默认值参数传递值,新值会覆盖默认值。
def func(var1, var2='Zhang') print(var1, var2) func('Leo')
参数收集
当时用的参数数量不确定的时候,可以使用参数收集的方式传递多个参数,传递的实参以元组形式存放。
这种参数名前加 * 表示。
应当注意:
- 型参中只能由一种这样的参数。
- 尽量将这种参数放在型参列表的尾部。
- 出现在这种参数之后的参数,只能使用关键字调用(想想print函数)。
def func(*args): print(f'number of args: {len(args)}') print(args) func('Leo', 'Zhang') output: number of args: 2 ('Leo', 'Zhang')
关键字参数收集
当有不确定数量的关键字参数时,可以使用关键字参数收集,将收集到的关键字实参封装为字典存放。
这种参数名前加 ** 表示。
应当注意:
- 型参中只能由一种这样的参数。
- 必须将这种参数放在型参列表的尾部。
def func(**kargs): print(kargs) func(name = 'Leo', age = '41') output: {'name': 'Leo', 'age': '41'}
逆向参数收集
将序列对象传递给函数,按照一定规则将序列对象的元素分配给型参。
应当注意:
实参为元组或者列表时,元素的数量应当与型参相同。
实参为字典时,元素的key必须与型参名字相同。
def func(var1 , var2): print(var1, var2) arg1 = ['Leo', 'Zhang'] arg2 = {'var1': 'Leo' , 'var2':'Zhang'} func(*arg1) func(**arg2)
参数传递机制
不可变类型作为参数传递给函数后,按值传递的机制会复制一份传递,对于实参的任何操作都不会影响实参的值。
def func(name): name = 'IT: ' + name #修改传递的参数 print(name) #IT: Leo if __name__ == '__main__': my_name = 'Leo' func(my_name) print(my_name) #Leo
可变类型作为参数传递给函数后,因为传递的是可变类型的地址,对于参数的任何操作都会影响实参的值。
def func(name_list,name): name_list.append(name) #name_list作为可变参数被添加了新值。 if __name__ == '__main__': names = [] func(names, 'Leo') print(names) #['Leo']
return返回值
函数执行到return,会立即返回。return后面的语句不会执行。
return可以多个值,自动封包为元组。
不定义return的时候,函数返回一个None。
def demo(): return 1,2,3 if __name__ == '__main__': result = demo() print(result) # -> (1, 2, 3)
Lambda表达式
Lambda匿名函数,使用lambda关键自定义。 func = lambda 逗号分割的参数列表: 表达式主体
Lambda表达式主体只能放一个语句。Lambda自带return语句。
Lambda表达式支持的参数形式和正常函数一致。
func = lambda x, y: x + y args = (1,2) print(func(*args)) #3
异常处理
所有的异常都派生于BaseException类,不同的类记录了不同的异常信息。
异常处理的结构
try:
可能发生异常的语句
except 异常类型 [as 别名]:
异常处理语句
except Exception [as 别名]:
异常处理语句
[else:
没有异常发生所处理的语句]
[finally:
有无异常一定处理的语句]
如果有多个except,处理异常的时候会去找最准确的异常类型,如果找不到在看有没有父类的异常类型,所以exception会在没有匹配上的时候在执行这个异常处理的分支。
finally分支用来进行资源的回收,无论try分支是否有异常,都会执行finally分支。
资源的回收包括: 打开文件、建立的网络套接字、数据库连接、多线程多进程。
触发异常
raise关键字主动抛出异常raise Exception
。
raise Exception('异常信息说明')
raise TypeError('This s a user-defined exception message....') output: Traceback (most recent call last): File "/home/leo/PycharmProjects/Fidelio/main.py", line 1, in <module> raise TypeError('This s a user-defined exception message....') TypeError: This s a user-defined exception message....
内置电池函数
基本函数
round(数值, 小数位) : 四舍五入
bool(对象) 判断对象是否为空。当变量为数字0,None,空字符串或者空序列的时候,得到的结果为False。
reverved(列表) 将列表反转,返回列表。
sorted(列表) 将列表排序,返回列表。
range(开始值,结束值,步长) 返回从开始到结束值-1 的 range对象。
zip(集合1 , 集合2) 返回zip对象,集合1与集合2 索引相同的值作为zip对象的元素。
a = (1, 2, 3) b = ('a' ,'b', 'c') print(list(zip(a,b))) ==> [(1, 'a'), (2, 'b'), (3, 'c')]
enumerate(集合) 将每个集合的值的索引与值形成一个数组。
a = (1,2,3) list(enumerate(a)) ==> [(0, 1), (1, 2), (2, 3)] for i,d in enumerate(a): print(i,d) 0 1 1 2 2 3
文件
file = open(文件路径 , 'r') 打开文件
file = open(文件路径 , 'w') 清空写入文件
file = open(文件路径 , 'a') 追加写入文件
for line in file : 针对文件每行进行扫描,遇到\n 结束本行。
file.read(size) 返回文本文件的所有内容 或者 size个字符的内容。
file.readline() 读取一行的内容。
file.readlines() 将文件的内容读到一个列表中,每行是列表的一个元素。
file.seek(行号) 移动文件读取的指针。
file.tell() 显示当前指针的位置。
file.write(内容) 写入一行数据
file.writelines(字符串列表) 将列表的每个元素作为一行写入文件。
file.close() 关闭文件
面向对象
创建类和实例
class 类名:
类的语句
class 类名(父类) :
类的语句
类名的首字母需要大写。
类名() 创建了一个实例。
面向对象编程
面向对象的三大特征:
- 封装
- 继承
- 多态
封装
将类的属性和方法包含到类中。
构造方法 __init__ 将属性绑定到类的对象。
self代表将被创建出来的类的对象。
class User: def __init__(self,name, age, major): self.name = name self.age = age self.major = major def __str__(self): print(f'{self.name}\'s age is {self.age} and major is {self.major}',end='') return '' user1 = User('Leo', 30, 'History') user2 = User('Kevin',34, 'Math') print(user1) -> Leo's age is 30 and major is History print(user2) -> Kevin's age is 34 and major is Math #self 参数用来指明创建出来的属性绑定到哪个对象。
类的方法中也可以添加类的属性,所添加的属性在类中可以全局调用。
class User: def __init__(self, name): self.name = name def set_age(self, age): self.age = age def get_age(self): print(self.age) user1 = User('leo') user1.set_age(30) -> 这里产生了一个属性age user1.get_age() -> 查询类属性age
实例方法、类方法、静态方法
实例方法:首个参数是self,绑定给类的实例调用的,类本身不能调用。
类方法:首个参数是cls,并以classmethod修饰的方法,类可以直接调用,类的实例也能直接调用。类的属性在类方法中是无法使用的。
静态方法:无首个参数,使用修饰器staticmethod修饰的方法,类可以直接调用,类的实例也能直接调用。类的属性在类方法中是无法使用的。
class User: def __init__(self, name): self.name = name @classmethod def cls_method(cls, name): print(name) @staticmethod def sta_method(name): print(name) User.cls_method('Leo') #-> Leo User.sta_method('Winston') #-> Winston
动态的添加属性和方法
动态添加属性
为类添加的属性影响所有类的实例。为对象添加属性只影响单个对象。
class User: def __init__(self, name): self.name = name if __name__ == '__main__': user1 = User('Leo') User.age = 30 ->为类添加动态属性 print(user1.age) -> 30 #虽然先创建的实例,添加类属性后,前面创建的对象也获得了这个属性。
动态添加方法
实例方法:只能单独为对象添加,不能为类添加。需要使用types模块来协助。只有在添加方法的对象可以调用,其他对象无法调用。
import types class Person: def __init__(self,name): self.name = name def say_hello(self): 定义需要添加到对象的方法 print('Hello World') if __name__ == '__main__': user = Person('Leo') user.say_hello = types.MethodType(say_hello, Person) 添加方法到对象。 user.say_hello()
类方法:使用@classmethod装饰器定一个类方法,然后复制给类。类和对象都可以调用。
class Person: def __init__(self,name): self.name = name @classmethod def say_hello(cls): print('Hi, I am newly added class method...') if __name__ == '__main__': Person.say_hello = say_hello Person.say_hello() -> Hi, I am newly added class method... user = Person('Leo') user.say_hello() -> Hi, I am newly added class method...
静态方法:使用@staticmethod装饰器定一个类方法,然后复制给类。类和对象都可以调用。
class Person: def __init__(self,name): self.name = name @staticmethod def get_rid_from_china(): print('No way...') if __name__ == '__main__': Person.get_rid = get_rid_from_china Person.get_rid() user = Person('Leo') user.get_rid()
继承
子类继承父类后,可以直接使用父类的属性和方法。
子类定义了和父类同名同参的方法,则会覆盖父类的方法。
class 类名(父类名):
类定义代码
class User: def __init__(self, name): self.name = name def show_message(self): print('Show message in user view') def add_message(self): print('Add a new message') class Admin(User): def show_message(self): print('Show message in admin view') if __name__ == '__main__': admin1 = Admin('Leo') 调用了父类的__init__(self, name)方法 admin1.show_message() 调用了子类覆盖父类的show_message admin1.add_message() 调用从父类继承的show_message
super()函数调用的方法
可以在子类中调用父类的任何方法。
如果父类的方法要传参,子类调用的时候同样要传递参数。
子类调用父类的方法时,方法定义的self指向的是子类而不是父类。
class Person: def __init__(self,name,age): self.name = name self.age = age def see(self): print('I can see you') class Teacher(Person): def __init__(self,name, age, school): super().__init__(name, age) #调用父类构造函数 self.school = school def see_student(self): super().see() #调用父类的方法 if __name__ == '__main__': leo = Teacher('Leo', 30, 'Collins') leo.see_student() #I can see you print(leo.name, leo.school) #Leo Collins
对于属性的继承
全部保留属性:子类不重写父类的__init__函数,就会全部保留父类的属性。
全部替换属性:子类重写父类的__init__函数,父类的__init__函数因为不调用,所以父类的属性都不存在。
class Vehicle: def __init__(self, brand, wheel): self.wheel = wheel self.brand = brand class Car(Vehicle): def __init__(self, manufacturer): self.manufacturer = manufacturer if __name__ == '__main__': my_car = Car('Japan')
部分保留,无新增:子类的__init__函数使用super()调用父类的__init__函数,用不到的参数传递None。
class Vehicle: def __init__(self, brand, wheel): self.wheel = wheel self.brand = brand class Car(Vehicle): def __init__(self, brand): -> 只使用brand参数创建car对象 super().__init__(brand, wheel=None) ->使用None去掉不需要的属性 self.model = model
部分保留,有新增:子类的__init__函数使用super()调用父类的__init__函数,用不到的参数传递None。也新加子类专用的属性。
class Vehicle: def __init__(self, brand, wheel): self.wheel = wheel self.brand = brand class Car(Vehicle): def __init__(self, brand, model): ->新增一个model属性,使用brand,model参数创建新对象 super().__init__(brand, wheel=None) ->使用None去掉不需要的属性 self.model = model
类变量
在类中定义的变量,不是类的属性。
使用类来访问和修改类变量。实例只能访问但无法修改类变量。
类对变量的访问顺序:
实例的属性(动态添加) -> 类的属性 -> 类变量 -> 父类的属性 -> 父类的类变量 -> 再继续往父类找....
class User: var = 10 def __init__(self,name): self.name = name if __name__ == '__main__': print(User.var) a = User('a') #10 print(a.var) #10 User.var = 100 print(a.var) #10 a.var = 50 #实例改变不了类变量,只是给自己动态增加了一个属性。 print(a.var) #50 print(User.var) #100
类方法和静态方法可以访问和修改类变量
class User: var = 10 @classmethod def change_var(cls, new_var): User.var = new_var @staticmethod def modify_var(new_var): User.var = new_var def __init__(self,name): self.name = name if __name__ == '__main__': User.change_var(200) print(User.var) User.modify_var(250) print(User.var)
常用模块
re模块
用来创建正则表达式,用来验证和查找符合规则的文本。广泛用于搜索引擎和账号密码的验证。
正则表达式预定义字符
\d : 匹配十进制数字。
\D : 匹配所有的非数字。
\s : 匹配所有空白字符, 空格,tab。
\S :匹配所有非空字符和下划线。
\w : 匹配所有字母、汉字、数字。a-z, A-Z, 0-9.
\W : 匹配所有字母、汉字、数字和下划线。
import re str1 = '[我是你爷爷abcd] 1234' finded = re.search('\d\d\d', str1) #从字符串匹配三个连续数字,从后往后找。 print(finded.group()) # 第一个匹配的是123
正则表达式特殊字符
^ : 文本的开头
$ : 文本的结尾
* : 前面的字符出现0次或者多次。
+ : 前面的字符出现1次或者多次。
? : 前面的字符出现0次或者多次,但变变贪婪模式为勉强模式匹配。
贪婪模式匹配出的字符串尽量的长,勉强模式匹配的字符串尽量的短。
. : 匹配除了\n以外的任何单个字符。
| : 使用竖线左右的正则表达式进行匹配。
import re str1 = '[我你是你爷爷爷爷abcd] 你爷爷, 你爷1234' finded_star = re.findall('你爷*', str1) #从字符串匹配你[爷0-无限次] finded_plus= re.findall('你爷+', str1) #从字符串匹配你[爷1-无限次] finded_question = re.findall('你爷?', str1) #勉强模式从字符串匹配。 finded_dot = re.findall('.*', str1) finded_or = re.findall('你爷+|\d', str1) print(finded_star) # ['你', '你爷爷爷爷', '你爷爷', '你爷'] print(finded_plus) #['你爷爷爷爷', '你爷爷', '你爷'] print(finded_question) #['你', '你爷', '你爷', '你爷'] print(finded_dot) #['[我你是你爷爷爷爷abcd] 你爷爷, 你爷1234', ''] print(finded_or) #['你爷爷爷爷', '你爷爷', '你爷', '1', '2', '3', '4']
[ ] : 代表一个集合。
- [abc] -- 匹配指定的单个字符。
- [a-zA-Z0-9 ] -- 匹配范围内的单个字符,可取反。 [^表达式] 取反。
- [0-5][0-9] -- 可以组合匹配。
import re str1 = '我的名字是zhangsan,我的电话是18660236631' str1 = '86, 71, 99, 97,00' find1 = re.findall('[5-9][5-9]|0', str2) print(find1) #['86', '99', '97', '0', '0'] find3 = re.findall('[^a-zA-Z0-9,]+',str1) #取反 print(find3) #['我的名字是', ',我的电话是']
{ } : 标记前面字符出现的频率。
- {m, n} -- 前面字符最少m次,最多n次。
- {m, } -- 前面字符最少m次,上不封顶。
- { , n} -- 前面字符最多出现m次,最少一次都可以不出现。
- { n } -- 前面字符最少出现n次。
正则表达式合理字符
\t : 制表符
\n : 换行符
\r : 回车符
\f : 换页符
\a : 报警符
\e : Escape符
匹配方法 match, search
re.match将目标文本与正则表达式进行匹配。
如果匹配成功,将返回一个匹配对象,对象中包含匹配到的第一个子串。
如果匹配不成功,将返回None。
-
match 在目标文本的开头进行匹配。
import re str1 = 'https://www.baidu.com' not_find = re.match('www', str1) do_find = re.match('ht+p\w+', str1) print(not_find) # -> None print(do_find) # -> <re.Match object; span=(0, 5), match='https'>
-
search 在整个目标文本中进行匹配。
import re while True: email_addr = input('Please input email: ') match_result = re.search('\w+\.\w+@\w+\.\w+', email_addr) print(match_result)
查找方法 findall, finditer, fullmatch
-
findall 扫描整个字符串,将与规则相匹配的子串拿出来组成列表。 没有匹配的字符串,返回空的列表。
import re str1 = 'https://mail.163.com/email/webmail' finded = re.findall('\w{,3}mail',str1) print(finded) # -> ['mail', 'email', 'webmail']
-
findall 扫描整个字符串,将与规则相匹配的子串组成一个迭代器。 没有匹配的字符串,返回空的迭代器。
import re str1 = 'https://mail.163.com/email/webmail' finded = re.finditer('\w{,3}mail',str1) for i in finded: print(i) output: <re.Match object; span=(8, 12), match='mail'> <re.Match object; span=(21, 26), match='email'> <re.Match object; span=(27, 34), match='webmail'>
-
fullmatch 要求整个字符串完全符合规则,否则返回None。
import re str1 = 'https://mail.163.com' finded = re.fullmatch('\w*.//\w*\.\w*\.\w*',str1) #正则必须完全匹配文本 print(finded) # -> <re.Match object; span=(0, 20), match='https://mail.163.com'>
工程目录
将不同的代码分开,不同功能的代码放在不同的目录中。
每个子目录设置为不同的模块包,方便调用。
主流的子目录:
- bin目录,放置主逻辑,main.py。
- log目录,放置日志文件。
- db目录,存放数据库目录。
- data目录,存放普通数据文件,txt,json等。
一定要有readme文件,readme包含:
-
那个目录做什么用的
-
包含的方法,函数,类的说明。
这篇关于Python的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24Python编程入门指南
- 2024-12-24Python编程基础入门
- 2024-12-24Python编程基础:变量与数据类型
- 2024-12-23使用python部署一个usdt合约,部署自己的usdt稳定币
- 2024-12-20Python编程入门指南
- 2024-12-20Python编程基础与进阶
- 2024-12-19Python基础编程教程
- 2024-12-19python 文件的后缀名是什么 怎么运行一个python文件?-icode9专业技术文章分享
- 2024-12-19使用python 把docx转为pdf文件有哪些方法?-icode9专业技术文章分享
- 2024-12-19python怎么更换换pip的源镜像?-icode9专业技术文章分享