三元表达式
1.介绍
1.也称三目运算符:用于简化 if...else...的语法结构
2. 只能解决if...else...结构,其他if分支结构都不管
3.一个分支提供一个结果: 如果一个分支提供了多个结果, 将多个结果通过元组返回
2.使用
语法:
条件成立的结果 if 条件 else 条件不成立的结果
a = int(input('a: '))
b = int(input('b: '))
res = a if a > b else b
print(res)
列表和字典推导式
1.介绍
快速生成列表或字典的语法糖,且能在生成过程中添加简单的逻辑
2.使用
1. 能被列表推导式推导的数据源必须在循环取值时可以得到一个值
ls = [v for v in range(1, 6)]
print(ls) # [1, 2, 3, 4, 5]
ls = ['奇数' if v % 2 != 0 else '偶数' for v in range(1, 6)]
print(ls) # ['奇数', '偶数', '奇数', '偶数', '奇数']
2.能被字典推导式推导的数据源必须在循环取值时可以被解压赋值为两个值
ls = [['A', 1], ('B', 2)]
res = {k.lower(): v for k, v in ls}
print(res)
函数对象
1.在python中,所有变量存放的值只要是地址,我们就称之为对象
# -- 所有的变量都是用来存放地址的,所以都是对象
# -- 存放整型的地址就是整型对象 | 存放函数的地址就是函数对象 | 存放文件的地址就是文件对象
2.函数对象:存放函数地址的变量就是函数对象
def fn(): pass
my_fn = fn
# my_fn | fn都存着函数地址,所以都是函数对象,函数对象的使用就是 函数对象() 来调用函数
3. 函数对象的应用场景
# 1.函数对象()就是调用函数
# 2.函数对象可以直接作为变量赋值给其他变量
# 3.函数对象可以作为函数的参数
# 4.函数对象可以作为函数的返回值
# 5.函数对象可以作为容器类型的成员
示例:
# 1.函数对象()就是调用函数
def fn1():
pass
fn1()
# 2.函数对象可以直接作为变量赋值给其他变量
def fn2():
pass
my_fn = fn2
print('>>>', my_fn, fn2)
my_fn()
# 3.函数对象可以作为函数的参数
def fn3(func): # func = my_fn = fn2
func()
fn3(my_fn)
# 4.函数对象可以作为函数的返回值
def fn4():
return my_fn
my_fn2 = fn4()
# 5.函数对象可以作为容器类型的成员
ls = [my_fn, my_fn2]
名称空间
1.名称空间:就是名字与地址的对应关系,可以被Python解释器遍历查找,采用堆栈存储方式
2.三种名称空间
# Built-in:内置名称空间;系统级,一个;随解释器执行而产生,解释器停止而销毁
# Global:全局名称空间;文件级,多个;随所属文件加载而产生,文件运行完毕而销毁
# Local:局部名称空间;函数级,多个;随所属函数执行而产生,函数执行完毕而销毁
3.注:文件中的if、while、for、with这些能产生缩减的关键字并不能产生名称空间
4.加载顺序:Built-in > Global > Local
5.名字的查找 (******)
1.需要先确定你当前在哪(大前提)
1.站在全局: 全局 >>> 内置
2.站在局部: 局部 >>> 全局 >>> 内置
作用域
1.作用域:变量(名字|对象)起作用的范围
2.四种作用域
# Built-in:内置作用域:作用所有文件的所有地方
# Global:全局作用域:作用当前文件的所有地方
# Local:局部作用域:作用当前函数内部
# Enclosing:嵌套作用域:作用当前函数已内部被嵌套函数
# 注:
# 不同作用域之间名字不冲突,以达到名字的重用
# 每个作用域优先使用自己作用域中的名字,没有再找更大的名称空间的名字,直到内置,还没有就报错
# 查找顺序:
Enclosing>Local> Global > Built-in
global关键字
1.作用:将局部的变量提升为全局变量
# 1.全局没有同名变量,直接提升局部变量为全局变量
# 2.有同名全局变量,就是统一全局与局部的同名变量
# -- 如果局部想改变全局变量的值(发生地址的变化),可以用global声明该变量
num = 888
def fn1():
global num
# print(num)
# 没有global修饰,num就是自己局部的变量
# 有global修饰,num就是全局的num,全局中只能出现一个num,如果出现了值的改变,大家一起变
num = 666
def fn2():
print(num) # 666
fn1()
fn2()
nonlocal关键字
1.作用:嵌套将局部的变量提升为局部变量
# 1.必须有同名嵌套局部变量,就是统一嵌套局部与局部的同名变量
# -- 如果局部想改变嵌套局部变量的值(发生地址的变化),可以用nonlocal声明该变量
def outer():
num = 888
def inner():
nonlocal num
num = 666
print(num) # 666
inner()
print(num) # 666
outer()
函数装饰器
一.开放封闭原则
1.开放封闭原则:在不修改源代码与调用方式的情况下为函数添加新功能 *****
# 开放:有些事,你可以干 - 拓展功能
# 封闭:有些事,你干不了 - 两个原则
# 1.不能修改源代码 - 1.无权修改 2.功能不特有 3.修改的位置多个,需要一一修改
# 2.不能修改原函数的调用方式 - 修改调用方式的弊端,原项目的所有函数调用都要修改
二.闭包函数
1.什么是闭包函数
闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数引用了外部函数作用域的名字
2.闭包示例
def outter():
x = 111
def inner():
print(x)
return inner
res = outter() # res就是inner函数内存地址
三.装饰器
1.简介
2.装饰器简单公式示例
# @outer语法来调用outer,规定传入被装饰的函数对象,所以参数固定为一个,接受被装饰的函数对象
from functools import wraps
def outer(func):
@wraps(func) # 系统的wraps带参装饰器:改变inner的假指向,本质外界使用的还是inner,但是打印显示的是wraps中的函数
# 不能确定被装饰的函数的参数:来者不拒,用可边长来接受
def inner(*args, **kwargs):
print('执行被装饰函数之前 你可以执行的操作')
res = func(*args, **kwargs) # 解压带给原功能
print('执行被装饰函数之后 你可以执行的操作')
return res
return inner
# 使用装饰器(outer),得到新功能(inner)
# 用被装饰的函数名去接受装饰器的执行结果,调用装饰器时传入被装饰的函数对象
@outer # fn = outer(fn) = inner
def fn(): pass
# 表面感觉调用的是原函数,本质调用的是闭包(inner),使用fn调用和fn定义及inner需要参数统一
fn()
4.带参装饰器
# 通常,装饰器为被装饰的函数添加新功能,需要外界的参数
# -- outer参数固定一个,就是func
# -- inner参数固定同被装饰的函数,也不能添加新参数
# -- 可以借助函数的嵌套定义,外层给内层传参
def wrap(info):
def outer(func):
# info = 0
def inner(*args, **kwargs):
print('新:拓展的新功能,可能也需要外界的参数%s' % info)
res = func(*args, **kwargs)
return res
return inner
return outer
@wrap('外部参数') #fn = wrap(info): fn = inner函数的内存地址
def fn(): pass
3.一个函数被多次装饰
def outer(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
return inner
def check_user(func):
def inner(*args, **kwargs):
# 账号的验证功能
user = args[0] # type: str
if not (user.isalpha() and len(user) >= 3):
print('账号不合法')
return False
res = func(*args, **kwargs)
return res
return inner
def check_pwd(func):
def inner(*args, **kwargs):
pwd = args[1]
if len(pwd) < 3:
print('密码不合法')
return False
res = func(*args, **kwargs)
return res
return inner
def format_return(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
if res:
return '登录成功'
return '登录失败'
return inner
# 登录的原功能
@format_return
@check_user
@check_pwd
def login(user, pwd):
if user == 'owen' and pwd == '123':
return True
return False
user = input('user: ')
pwd = input('pwd: ')
res = login(user, pwd)
print(res)
# 执行过程:调用login => 进入第一个装饰器(format_return)的inner => 进入第二个装饰器(check_user)的inner => 进入第三个装饰器(check_pwd)的inner => 开始返回,从第三个返回到第二个再返回到第一个,最后返回到外界调用的位置
4.登录装饰器示例
def login_auth(func):
from core import src
def inner(*args, **kwargs):
if src.user_info['name']:
print('已登录!')
res = func(*args, **kwargs)
return res
else:
src.login()
return inner
枚举对象
1.给可迭代器对象及迭代器对象添加迭代索引
2.基础语法:enumerate(对象,start=开始索引,默认为0)
--默认索引从0开始
示例1:
s1 = ['a','b','c']
print(enumerate(s1)) #<enumerate object at 0x000002301BACCD38>
for v in enumerate(s1):
print(v) # (0 'a') | (1 'b') | (2 'c')
示例2:
s1 = ['a','b','c']
print(enumerate(s1)) #<enumerate object at 0x000002301BACCD38>
for v in enumerate(s1,start=1):
print(v) # (1 'a') | (2 'b') | (3 'c')