内层定义了和外层同名的变量
内层优先使用内层定义的变量,即是定义的变量的代码在内层的最后面
解决办法:当内层存在和外层同名变量,而且内层需要使用外层定义的变量,此时应该使用
nonlocal 关键字进行约束
装饰器的作用:不修改源代码的基础上,给函数增加新的功能
装饰器使用:
- 存在闭包
2)需要装饰的函数
写法:
@闭包的外层函数名
def 待装饰的函数():
普通参数
待装饰
@functioin_out
def login(num):
注意:
1)function_in(参数)
2)func(参数)
可变参数
待装饰
@functioin_out
def login(*args, **kwargs):
注意:
1)function_in(*args, **kwargs)
2)func(*args, **kwargs)
错误用法:
func(args,kwargs)
func(*args,**kwargs)
改为 return func(*args,**kwargs)
作用:向装饰器内部传递参数
格式:
def test(path):
def function_out(func):
def function_in():
....
return function_in
return function_out
使用:
@test("login.py")
test(login.py) ---> function_out
@ 第一步的结果 ——> @ founction_out
作用:使用一个类为一个函数装饰
类的书写:
必须有两个方法
- init 方法,必须接收 装饰器传递的参数 func
2)call方法, self.func()
# 装饰器类
class Test(object):
def __init__(self,func):
print("----init----方法")
print("---func--", func)
# func 是login函数的引用
self.func = func
def run(self):
print("---正在疯跑---")
def __call__(self, *args, **kwargs):
print("----开始验证----")
# 调用原来login的内容
self.func()
格式:@类名
待装饰的函数
@Test
def login():
login = Test(login)
login() ---> 调用类的
__call__
方法
对象名() 调用对象的 __call__()
可变类型(mutable),创建后可以继续修改对象的内容(值)
字典、列表
不可变类型(unmutable) ,一旦创建就不可修改的对象(值)
数字, 字符串,元组
当内容发生修改,计算机重新分配一块内存空间
深拷贝:
浅拷贝
简单可变类型的拷贝总结:
简单可变类型的数据不管深拷贝还是浅拷贝,都会产生新的空间,而且保持各自的独立性
存在的问题:当我们把模块文件放到工程文件夹的外部的文件,发现无法正常引入模块
原因: 外部的文件夹的路径,没有放到环境变量中
查看环境变量
- 导入 sys模块
- sys.path 查看环境变量 返回值是列表
把自己写的模块的路径加入到环境变量中
import 导入模块后,如果模块被修改,此时再次 import 不起作用
import 自动防止重复包含
强制重新加载一次模块
reload() 函数
- from imp import reload
- reload(要重新加载的模块)
私有化: 模块中的一些变量不希望被其他模块导入,可以使用私有化解决
私有化使用的前提:必须使用 “ from xxx import * “
用法: 在模块中,把变量前增加一个下划线 _变量名
注意:如果使用其他的方式导入模块,私有化将无效
from xxx import _私有变量
print(_私有变量) 不会报错
super() 使用的时候,传递参数的时候,self 不用传递
super() 调用顺序,按照 mro顺序来完成
Grandson.__mro__
是一个元组当在类中使用 super() 在 mro列表中找到当前类的下一个元素,调用该元素的方法
多继承中 super() 执行顺序,严格执行 MRO顺序表
MRO顺序表:
类名.__mro__
注意:
当在类中使用 super() 在 mro列表中找到当前类的下一个元素,调用该元素的方法
多继承中,不建议使用类名 直接调用父类的方法
@property 的特点: 让我们通过对象.方法名的方式可以调用方法
语法格式:
@proerty
def xxx(self):
? pass
注意:
@property 装饰的方法,只能有一个参数self
经典类: @property 一种方式
新式类:
@property
goods.price 获取价格的方法
@xxx.setter
goods.price = xxx
@xxx.deleter
del goods.price ---> @xxx.delete 装饰的方法
定义 property 对象的类属性
xxx =property(参数1,参数2,参数3,参数4)
第一个参数,当我们 foo.BAR 自动调用第一个参数的方法 第二个参数,当我们 foo.BAR = 100,自动调用第二个参数的方法 第三个参数,当我们 del foo.BAR ,自动调用第三个参数的方法 第四个参数,当我们 Foo.BAR.__doc__,自动获取第四个参数的内容
使用
类.xxx.__doc__
获取第四个参数的内容魔术属性
__doc__
获取描述信息
类名.__doc__
对象.方法名.__doc__
__module__
获取所属的模块(对象名.__module__
) 直接改文件 获取的__main____class__
获取对象所属的类 对象名.__class__
魔术方法
__init__
初始化方法 类名() 自动调用
__del__
删除对象的时候,会调用 del 对象
魔术属性__dict__
获取对象或者类的信息
对象名.__dict__
对象的实例属性信息类名.__dict__
模块、类描述、对象方法...魔术方法
__call__()
当使用 对象名() 会调用该方法__str__()
打印对象的会调用 print(obj) str方法一定要return,而且return 一定字符串内容__getitem__
对象[‘xxx‘]__setitem__
对象[‘xx‘] = xxx__delitem__
del 对象[‘xx‘]上下文:以 with open 来说,打开文件在上文 关闭文件在下文
上下文管理器:
__enter__
上文方法__exit__
下文方法自定义一个满足满足上下文管理器的 类
"""
类: MyFile()
类方法:
1. __enter__() 上文方法
2. __exit__() 下文方法
3. __init__() 方法,接收参数并且初始化
with MyFile(‘hello.txt‘, ‘r‘) as file:
file.read()
"""
class MyFile(object):
# 1. __enter__() 上文方法
def __enter__(self):
print("进入上文....")
# 1,打开文件
self.file = open(self.file_name, self.file_model)
# 2,返回打开的文件资源
return self.file
# 2. __exit__() 下文方法
def __exit__(self, exc_type, exc_val, exc_tb):
print("进入下文....")
# 关闭文件资源
self.file.close()
# 3. __init__() 方法,接收参数并且初始化
def __init__(self, file_name, file_model):
# 保存文件名和文件打开模式,到实例属性中
self.file_name = file_name
self.file_model = file_model
if __name__ == ‘__main__‘:
with MyFile("hello.txt", "r") as file:
# 开始读取文件
file_data = file.read()
print(file_data)
装饰器
待装饰的函数
myopen() 分拆成上文和下文,使用yield 分拆
def myopen(file_name,file_model):
print("进入上文")
# 1.打开文件
file = open(file_name,file_model)
# 2.返回资源
yield file
print("进入下文")
# 下文
# 3. 关闭资源
file.close()
装饰的过程:
导入模块 from contextlib import contextmanager
第二步:
@contextmanager
def myopen(file_name,file_model):...
原文:https://www.cnblogs.com/yangxuezhi/p/15260690.html