文章目录
一、函数命名空间
1.*与**在实参中的作用
*在形参中的作用
接收多余的位置参数并组织成元组的形式赋值给*后面的变量名
**在形参中的作用
接收多余的关键字参数并组织成字典的形式赋值给**后面的变量名
2.命名关键字参数(冷门了解)
需要形参在传实参的时候 必须按照关键字参数才可以 在*args 后面加上关键形参
下面实参加上数据值即可
如果形参中还有**kwargs 那必须在它的前面
def func(a,b,*args,c,**kwargs):
pass
func(1,2,3,4,5,6,c=123,name='meijin')
3.名称空间
就是用来存放变量名与数据值之间绑定关系的地方
内置空间
内置名称空间就是python解释器一打开就默认创建的空间
写代码过程中可以直接使用的名字都在该空间中(print、len、input)
全局空间
py文件运行代码过程中产生的变量名都会存入该空间
1.普通代码里面的变量名 2.分支结构里面的变量名 3.循环结构里面的变量名
4.定义函数的函数名 5.定义类的类名
局部空间
函数体代码运行过程中产生的名字都会存入该空间
4.名称的查找顺序
寻找变量名之前一要先看自己是那个空间
1.当前在全局名称空间
全局名称空间 >>>: 内置名称空间
2.当前在局部名称空间
局部名称空间 >>>: 全局名称空间 >>>: 内置名称空间
如果三个空间中都没有这个变量名那结果就报错不存在
名字的查找顺序默认情况下不能颠倒只能是 局部>>>:全局>>>:内置
5.名称空间的作用域
1.内置名称空间
在程序任意位置都可以使用(全局有效)随时调用
2.全局名称空间
在程序任意位置都可以使用(全局有效)随时调用
3.局部名称空间
在各自的局部空间可以使用(局部有效)调用的时候才有用
只能在自己的空间里面使用 别的局部空间数据用不到
6.局部名称空间复杂情况
1.各自局部名称空间默认情况下不能彼此共享名字
def func1():
name = 'meijin'
print(age)
def func2(): 结果肯定是报错的
age = 18 在各自的局部空间可以使用(局部有效)
print(name)
func1()
func2()
2.局部案例怎样拿到其他局部的变量名:嵌套式函数
x = 1
def func1():
x = 2
def func2():
x = 3 当本层函数没有x再在外层局部寻找X
def func3(): 外层的局部空间也没有x就在全局空间找
print(x) 全局没有找内置空间 内置空间没有报错
func3()
func2()
func1()
7.global与nonlocal关键字
global
主要是局部空间修改全局空间的不可变类型变量数值
nonlocal
主要是修改局部空间的不可变数据类型变量数值
需要修改可变类型的时候需要声明 global = 全局空间的变量名
l1 = [1, 2, 3, 4, 5]
s = '$meijin$'
def func():
global s 修改全局的变量名S
s = 'meijin' 新数据值
l1.append(113123) 尾部追加113123
l1.append(666) 再次追加
func()
print(l1) [1, 2, 3, 4, 5, 113123, 666]
print(s) meijin
8.函数名的多种使用方式
1.函数名也可以被用来多次赋值(函数名与变量名使用一致)
2.函数名还可以当做函数的实参
3.函数名还可以当做函数的返回值
4.函数名还可以当做容器类型里面的数据值
实例请查看原文:http://t.csdn.cn/bfrbm
二、装饰器
装饰器本质?
在不改变被装饰对象原来的'调用方式'和'内部代码'的情况下给被装饰对象添加新的功能
eg:
def func():
print(123)
func() # 每次执行之前需要校验用户身份
'万能装饰器模版'
def outter(func_name)
def inner(*args,**kwargs)
print('这是函数被装饰之前')
res = func_name(*args,**kwargs)
print('这是函数装饰之后的')
return res
res inner
三、闭包函数
闭包函数
1.定义在函数内部的函数
2.内部函数使用了外部函数名称空间中的名字
ps:只有符合上述两个特征的函数才能称之为闭包函数
def outer(): 设置一个外层函数
x = 100 局部空间创建一个参数X=100
def inner(): 局部再建一个函数inner
print(x) 局部打印X找不到X向外层局部寻找X
return inner 返回 inner值 X 100 不要加括号哦!
f = outer() 函数名outer赋值给f
print(f) 打印f 得到outer函数体代码地址
f() 运行函数f
result: <function outer.<locals>.inner at 0x7f8ff8104550>/n100
实例请查看原文:http://t.csdn.cn/Zd9FF
四、多层装饰器
'''语法糖会将紧挨着的被装饰对象的名字当做参数自动传入装饰器函数中'''
eg:
def outer1(func1):
print('加载了outer1')
def wrapper1(*args,**kwargs):
print('执行了wrapper1')
res1 = func1(*args,**kwargs)
return res1
return wrapper1
def outer2(func2):
print('加载了outer2')
def wrapper2(*args.**kwargs):
print('执行了wrapper2')
res2 = func2(*args,**kwargs)
return res2
return wrapper2
def outer3(func3):
print ('加载了outer3')
def wrapper3(*args,**kwargs):
print('执行了warpper3')
res3 = func3(*args,**kwargs)
return res3
return wrapper3
@outer1
@outer2
@outer3
def index():
print('from index')
多层语法糖解读顺序是先看语法糖有几个,然后再由下往上去看,遇到最后一个才会使用相同的变量名传给装饰器函数使用
语法糖三:wrapper3 = outer3(index),加载了outer3
语法糖二:wrapper2 = outer2(wrapper3),加载了outer2
语法糖一;index = outer1(wrapper2),加载了outer1
执行顺序就是:wrapper1>>>>>wrapper2>>>>>wrapper3
加载outer3>>>加载outer2>>>加载outer1>>>运行wrapper1函数体代码
>>>然后再执行outer2函数体代码>>>然后再执行wrapper3的函数体代码>>>index()
五、有参装饰器
'''这是已知的用户登陆函数'''
def login_auth(func_name):
def inner(*args, **kwargs):
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if username == 'meijin' and password == '123':
res = func_name(*args, **kwargs)
return res
else:
print('用户权限不够 无法调用函数')
return inner
--------------------------------------------------------------------------------------------------------
def outer(condition,type_user):
def login_auth(func_name): # 这里不能再填写其他形参
def inner(*args, **kwargs): # 这里不能再填写非被装饰对象所需的参数
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 应该根据用户的需求执行不同的代码
if type_user =='meijin':
print('使用vip方式作为数据来源 比对用户数据')
if condition == '列表':
print('使用列表作为数据来源 比对用户数据')
elif condition == '字典':
print('使用字典作为数据来源 比对用户数据')
elif condition == '文件':
print('使用文件作为数据来源 比对用户数据')
else:
print('去你妹的 我目前只有上面几种方式')
return inner
return login_auth
@outer('文件','jason')
def index():
print('from index')
index()
六、递归函数
一、什么是递归函数
递归函数:函数中调用了自己的函数
def index(): 在全局寻找index 无限循环
print('from index') 上面说法其实也是错误的
index() 不会无限循环 python的循环次数是有限的
index() 官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)
import sys 倒入系统板块
print(sys.getrecursionlimit()) 内置方法. 1000是递归最大次数
sys.setrecursionlimit(2000) 可以自定义最大次数
print(sys.getrecursionlimit())
实例请查看原文:http://t.csdn.cn/7sWcI
七、三元表达式
什么是三元表本质?
是对简单的代码进行缩写 简单的来说就是偷懒的写法减少代码行数
基本格式
res = 条件成立时返回的值 if 条件 else 条件不成立时返回的值
a = 10
b = 22
正常写法 if a>b:
max = a
else:
max = b
三元表达式: max = a if a>b else b
列表: old_list = ['mei', 'jin', 'python', "n", 'b']
new_list = []
三元表达式: new_list = [name.upper() for name in old_list]
print(new_list)
result:['MEI', 'JIN', 'PYTHON', 'N', 'B']
字典 items = [('name', 'meijin'), ('age', 20), ('job', 'designder')]
三元表达式: res = {k: v for k, v in items if k != 'age'}
print(res)
result:{'name': 'meijin', 'job': 'designder'}
集合 name = ['name', 'like', 'meijin']
三元表达式 set1 = {key for key in name}
print(set1, type(set1))
result:{'meijin', 'like', 'name'} <class 'set'>
八、匿名内置函数
什么事匿名函数?
匿名函数就是没有函数名的函数(lambda)
语法结构
函数名 = lambda 参数 :返回值
参数可以有多个 用逗号隔开
匿名函数不管逻辑多复杂 只能写一行 且逻辑执行结束后的内容就是返回值
返回值和正常的函数一样可以是任意数据类型
ex:
print((lambda x: x + 1)(123)) 直接调用
res = lambda x: x + 1 命名调用
print(res(123))
result:124,124
实例请查看原文:http://t.csdn.cn/TetsO