Python语法基础篇(二)
- 类型转换
- 拷贝
- 可变对象与不可变对象
- 可变对象
- 不可变对象
- 函数
- 拆包
- 异常
- 模块
- 闭包
- 装饰器
?????一只正在努力学习计算机技术的小仓鼠,尾部有课程链接哦~?????
类型转换
int()
:转换成整型print(int(1.8 ) )
float()
:转换成浮点型print(float(5 ) )
str()
:转换成字符串print(str(5.00 ) )
eval()
:实现list、dict、tuple和string之间的转换 — 去引号,但是不安全(详见RCE)s = "[[1,2,3],[4,5,6]]" slist = eval(s) print(slist,type(slist) )
list()
:将可迭代对象转换成列表 注:可迭代对象指能用for循环遍历的对象;支持转换为list的类型: string、tuple、dict、set# str -> list print(list('abc' ) ) # tuple -> list print(list((1 ,2 ,3 ,4 ) ) ) # dict -> list print(list({ 'name':'zhangsan' , 'age':18 } ) ) # set -> list print(list({ 'a' ,'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,'h' } ) )
拷贝
- 深拷贝:创建一个新对象,新对象涵盖所有层级的对象属性和数组元素,新对象与原对象不共用内存。
import copy a = [1 ,2 ,3 ,[4 ,5 ,6]] acopy = copy.deepcopy(a) print(id(a) ,id(acopy) ) a[3].append(7 ) print(a,acopy)
- 浅拷贝:创建一个新对象,只复制指针,该指针指向与原数据共同的对象。
import copy a = [1 ,2 ,3 ,[4 ,5 ,6]] acopy = copy.copy(a) print(id(a) ,id(acopy) ) a[3].append(7 ) print(a,acopy)
- 浅拷贝与深拷贝的区别详解
可变对象与不可变对象
可变对象
- 概念:存储空间保存的数据允许被增加、删除或修改,但内存地址不会发生改变,这种数据就是可变类型。
Python中可变对象有list、set、dict
li = [1 ,2 ,3 ,4] print(li,id(li) ) li.append(5 ) print(li,id(li) )
不可变对象
- 概念:变量对应的值不能被修改,如果修改就会生成一个新的值从而分配新的内存空间。
Python中不可变对象有tuple、int、float、string
st = 'hello' print(id(st) ) st = 'bingbing' print(id(st) )
函数
- 概念:将独立的代码块组织成一个整体,使其具有特定功能。
- 普通函数
- 格式
def 函数名(): 函数体 return 返回值1, 返回值2 ... # 调用 函数名()
- 返回值类型
- 没有返回值:None
- 一个返回值:该值
- 多个返回值:元组
- 参数类型
- 必备参数,默认参数 注:必备参数必须在默认参数前面。
# x,y为必备参数;z为默认参数 def my_add(x,y,z=10 ): return x+y+z p = my_add(1 ,2 ) q = my_add(1 ,2 ,3 ) print(p,q)
- 可变参数:传入参数类型为元组,数量可以改变。
def afunc(*args): tuple_to_list = list(args) print(args) print(tuple_to_list) afunc(1 , 2 , [3 , 4] )
- 关键字参数:参数以字典的形式传值。
def bfunc(**kwargs): for i in kwargs.keys( ): print(i, type(i) ) print(kwargs[i] , type(kwargs[i] ) ) bfunc(name='zhangsan' ,age=18 )
- 必备参数,默认参数 注:必备参数必须在默认参数前面。
- 函数嵌套:在一个函数里定义另一个函数
def cfunc( ): print('this is cfunc' ) def dfunc( ): print('this is dfunc' ) # 定义和调用同级(同缩进) dfunc( ) cfunc( )
- 作用域:按照变量生效范围可分为全局变量和局部变量
- 全局变量
a = 100 def test1( ): print('a的值为%d' % a) test1( )
# 全局变量__name__ # 作用:用于控制py文件在不同的应用场景执行不同的逻辑 # 文件在当前程序执行:__name__ == '__main__' # 文件被当作模块导入时,不执行__name__ == '__main__' import pytest_1 pytest_1.test( ) # pytest_1.py print('这是pytest2作为模块会显示的内容' ) def test( ): print('哈哈哈' ) if __name__ == '__main__': print('这是pytest2作为模块不会显示的内容' )
- 局部变量
a = 120 def test2( ): a = 100 print('a的值为%d' % a) test2( ) print('a的值为%d' % a)
global 变量名
:将变量声明为全局变量,用于修改全局变量值a = 120 def test2( ): global a a = 100 print('a的值为%d' % a) test2( ) print('a的值为%d' % a)
nonlocal 变量名
:用于声明外层的局部变量def test3( ): a = 100 def inner_func( ): nonlocal a a = 120 print('a的值为%d' % a) inner_func( ) print('a的值为%d' % a) test3( )
- 全局变量
- 格式
- 匿名函数
- 无参数
funa = lambda : '一桶水果茶' fruit_tea = funa( ) print(fruit_tea)
- 必要参数
函数名 = lambda 形参:返回值(表达式)
add = lambda a,b:a+b #a,b就是匿名函数的形参,a+b是返回值的表达式 total = add(1 ,2 ) print(total)
- 默认参数:默认参数必须写在必要参数后面
funb = lambda name,age=18:(name,age) info_a = funb('张三' ) info_b = funb('李四' , 20 ) print(info_a,'\n' ,info_b)
- 可变参数
func = lambda **kwargs:kwargs print([func(name='张三' ,age=18 )] )
- lambda与if函数结合(三目运算符)
fund = lambda a,b:a if a<b else b print(fund(1 ,2 ) )
- 无参数
- 内置函数
- 查看所有内置函数:大写字母开头一般是内置常量名,小写字母开头一般是内置函数名
import builtins print(dir(builtins) )
abs()
:返回绝对值sum()
:求和 — 元组,集合,数组print(sum([2 ,3] ) )
min()
:求最小值max()
:求最大值print(min(-2 ,3 , key=abs ) )
zip()
:将可迭代对象作为参数,将对象中的元素一一对应打包成元组(如果元素不一致,就按照长度最短的返回)l1 = [1 ,2 ,3] l2 = ['a' ,'b'] print(zip(l1,l2) ) for i in zip(l1,l2): print(i, type(i) ) # 转换成列表打印(条件:必须是可迭代对象) print(list(zip(l1,l2) ) )
map(function, iterable)
:对可迭代对象中的每一个元素进行映射。list1 = [1 ,2 ,3] def func(a,b=1 ): return a+b # 对象形式的数据有两种提取方式: (1)数组 (2)for循环 print(list(map(func,list1) ) ) print(list(map(lembda a,b=1:a+b, list1) ) )
reduce(function, sequence)
:将对象中的两个元素取出作为函数的实参进行运算,运算的结果和第三个元素作为函数的实参再进行运算。function:必须是有且仅有两个必要参数的函数sequence:必须是可迭代对象
from functools import reduce list2 = [1 ,2 ,3] def add(x, y, z=1 ): return x+y+z print(reduce(add, list2) )
- 查看所有内置函数:大写字母开头一般是内置常量名,小写字母开头一般是内置函数名
- 递归函数
- 概念:如果一个函数在内部不调用其他函数, 而是调用它本身, 这个函数就是递归函数。
def acc(number): if number == 0: return 0 else: return number + acc(number-1 ) print(acc(10 ) ) # 斐波那契数列 def fabnacci(number): if number == 1 or number == 2: return 1 else: return fabnacci(number-1 ) + fabnacci(number-2 ) for i in range(31 ): if i > 0: print(fabnacci(i) , end=',' )
- 概念:如果一个函数在内部不调用其他函数, 而是调用它本身, 这个函数就是递归函数。
拆包
- 概念:对于函数中的多个返回数据,去掉元组、列表或字典,直接获取数据的过程
tua = (1 ,2 ,3 ) print(tua,type(tua) ) # 拆解方法一 a,b,c = tua print(a,b,c) # 拆解方法二 a, *b = tua print(a, *b) # 一般在函数调用时使用 def funa(a,b,*args): print(a,b) print(args,type(args) ) arg = [1 ,2 ,3 ,4 ,5 ,6] funa(*arg)
异常
- 概念:当Python检测到一个错误时,解释器就无法继续执行下面的语句,反而会出现一些错误的提示。
- 异常类型
异常类型 释义 AttributeError 尝试访问或设置一个对象不存在的属性或方法 IOError 输入/输出异常,例如无法打开文件 ImportError 无法引入模块和包,例如路径错误或名称错误 IndentationError 语法错误(的子类),例如代码没有正确对齐 IndexError 下标索引超出序列边界 KeyError 视图访问字典里不存在的键 SyntaxError 代码非法, 代码不能编译 TypeError 传入对象类型与要求的不符合 ValueError 传入一个调用者不期望的值 - 异常处理:程序有异常时,整个程序仍能正常运行
- 语法:
try: 可能引发异常现象的代码 except: 出现异常现象的处理代码 else: 只有在没有异常时才会执行的代码 finally: try代码块结束后执行的代码
- 示例:
# 方法1: try: print(abc) except NameError as e: print(e) # 方法2 -- 捕获任何异常 try: print(abc) except Exception as e: print(e) # 方法3 -- 多分支异常 try: print(abc) except IndexError as e: print(e) except KeyError as e: print(e) except NameError as e: print(e) # else dic = { 'name':'zhangsan' } try: print(dic['age'] ) except Exception as e: print('出现错误' ) else: print(dic) # finally try: print(dic['age'] ) except Exception as e: print(e) finally: print(dic)
- 语法:
- 抛出异常
raise
- 创建一个Exception(‘xxx’)对象
- raise抛出这个异常对象
# 需求:密码长度不足六位就重新输入,输入超过三次错误就报异常 def login( ): for i in range(3 ): pwd = input('请输入密码:' ) if len(pwd) >= 6: return '密码输入成功' elif i != 2: print('密码长度不足六位,请重新输入' ) raise Exception('输入错误超过三次,退出' ) try: login( ) except Exception as e: print(e)
模块
- 概念:一个py文件就是一个模块,即导入一个模块本质上就是执行一个py文件。
- 分类
- 内置模块:random、time、os、logging
- 第三方模块:pip install 包名
- 自定义模块:自己在项目中定义的模块
# 导入模块 import numpy # 调用功能 l1 = [1 ,2 ,3] l1 = numpy.append(l1,[4 ,5 ,6] ) print(l1) # 从模块中导入指定的部分 from numpy import split # as起别名 import pandas as pd
- 包
- 概念:项目结构中的文件夹/目录。包的本质是模块,包可以包含包。
- 作用:将有联系的模块放到同一个文件夹下,并且在该文件夹中创建一个__init__.py的文件。包能够有效避免模块名称的冲突问题,使结构更清晰。
# import导入包时, 首先执行__init__.py文件 # __all__ 本质是一个列表, 列表里面的元素代表要导入的模块。 # Pack_01是Python Package from Pack_01 import * Register.reg( ) # __init__.py # 不建议在__init__.py中写过多代码, 尽量保证init的内容简单 # 主要作用: 导入这个包内的其它模块 # from Pack_01 import Register __all__ = ['Register'] # Register.py def reg( ): print('这是reg函数' )
闭包
- 内部函数构成闭包的条件:
- 嵌套函数
- 内部函数使用外部函数的变量
- 外部函数返回内部函数
- 无参数
def funcA( ): a = 10 def funcB( ): print(a) return funcB # 第一种调用方法 print(funcA( ) ) funcA( )( ) # 第二种调用方法 ot = funcA( ) ot( )
- 默认参数
# 函数名保存函数地址,()理解成指针 def outer(m): n = 10 def inner(p): print(m+n+p) return inner ot = outer(5 ) ot(5 )
- 思维训练
def result(**kwargs): identity = { 'code':0 } identity['code'] = kwargs['add'] def tup(*args): for i in args: identity['code'] += i def outer(a,b=1 ): identity['code'] += a+b return kwargs.get('add' ) return outer return tup result(add=10 )(1 ,2 ,3 ,4 )(9 ) # 每次开启内函数都在使用同一份闭包变量 print(result(add=10 )(1 ,2 ,3 ,4 )(9 ) )
装饰器
- 概念:装饰器本质上是一个闭包函数,它可以让其他函数不需要做任何变动的情况下增加额外功能,装饰器的返回值是一个函数对象。
- 作用:在不改变原有代码情况下添加新的功能
- 条件:
- 不修改源程序或函数的代码
- 不改变函数或程序的调用方法
- 单个装饰器
# 形参是函数 def test(fn): print('test' ) fn( ) def HaHa( ): print('HaHa' ) test(HaHa) # 标准版装饰器 def send( ): print('send message' ) def outer(fn): def inner( ): # 原有功能 --- send() fn( ) # 新功能 print('check message info' ) return inner outer(send)( )
- 多个装饰器
def deco_1(fn): def inner( ): return "哈哈哈"+fn( )+"呵呵呵" return inner def deco_2(fn): def inner( ): return "nice"+fn( )+"excellent" return inner # 多个装饰器的装饰过程,距离函数最近的装饰器先装饰。 # deco_2 -> "nice"+test()+"excellent" # deco_1 -> "哈哈哈"+demo_2()+"呵呵呵" @deco_1 @deco_2 def test( ): return "晚上在学习python" print(test( ) )
- 语法糖
- 格式:
@装饰器名称
- 无参数
def outer(fn): def inner( ): fn( ) print('send message' ) return inner @outer def YYDS( ): print('YYDS' ) YYDS( )
- 有参数
# 有参数 user = [{ 'username':'zhangsan' , 'password':'123456' }] def outer(fn): def inner(user): for i in range(len(user) ): for j in user[i].keys( ): if j == 'username': print(f'用户:{ user[i][j] }' ,end=',' ) else: print(f'密码:{ user[i][j] }' ) fn(user) return inner @outer def login(user): while True: username = input('请输入用户名:' ) pwd = input('请输入至少六位密码:' ) if len(pwd) < 6: print('请重新输入' ) continue else: user.append({ 'username':username, 'password':pwd } ) break for i in range(len(user) ): for j in user[i].keys( ): if j == 'username': print(f'用户:{ user[i][j] }' , end=',' ) else: print(f'密码:{ user[i][j] }' ) login(user)
- 格式:
课程链接