文章目录
1、property属性
1.1、定义
property属性就是负责把类中的一个方法当作属性进行使用,可以简化代码
1.2、装饰器方式
class Person(object):
def __init__(self):
self.__age =0
@property
def age(self):
return self.__age
@age.setter
def age(self,new_age):
self.__age = new_age
p=Person()
print(p.age)
p.age=100
print(p.age)
1.3、类属性方式
property的参数
第一个参数是获取属性是要执行的方法
第二个参数是设置属性时要执行的方法
定义property属性有两种方式:1、装饰器方式 2、类属性方式
装饰器方式:1、property修饰获取值的方法
2、@方法名。setter修饰设置值的方法
类属性方式
1、property属性=property(获取值方法,设置值方法)
class Person(object):
def __init__(self):
self.__age = 0
def get_age(self):
return self.__age
def set_age(self,new_age):
if new_age>=150:
print("年龄错误")
else:
self.__age=new_age
age = property(get_age,set_age)
p=Person()
print(p.age)
# 设置属性
p.age=100
print(p.age)
2、with语句
python提供了with语句用于简化资源释放的操作,使用with语句操作建立在上下文管理器(实现 __ enter __ 和 __ exit __ 方法)的基础上
class File(object):
def __init__(self,file_name,file_model):
self.file_name = file_name
self.file_name= file_model
def __enter__(self):
print("这是上文")
self.file = open(self.file_name,self.file_model)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print("这是下文")
self.file.close()
with File("1.txt","r") as f:
file_data=f.read()
print(file_data)
3、生成器
3.1、作用
根据程序设计者指定的规则循环生成数据,当条件不成立时则生成数据结束。
数据不是一次性全部生成出来,而是使用一个,再生成一个,可以节约大量的内存
3.2、生成器推导式
与列表推导式类似,只不过生成器推导式使用小括号
data = (x for x in range(100))
next(data)
for i in data:
print(i)
生成器相关函数
next函数获取生成器中的下一个值
for循环遍历生成器中的每一个值
3.3、yield关键字
yield关键字生成器的特征:在def函数中具有yield关键字
def mygenerater(n):
for i in range(n):
print('开始生成....')
yield
print('完成一次.....')
g= mygenerater(5)
# print(next(g))
# print(next(g))
# print(next(g))
for i in g:
print(i)
1、代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
2、生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration异常,表示停止迭代异常
3、while循环内部没有处理异常操作,需要手动添加处理异常操作
4、for 循环内部自动处理了停止迭代异常,使用起来更加方便,推荐使用
3.4、生成器产生斐波纳锲数列
(前面两个数字相加) 1、2、3、5、8、13、21.。。。。。
def fb(num):
a =0
b=1
index =0
while index< num:
result = a
a,b = b,a+b
yield result
index +=1
f=fb(8)
for i in f:
print(i)
1、生成器时根据算法生成数据的一种机制 ,每次调用生成器只生成一个值,可以节省大量内存
2、生成器的创建
4、深拷贝和浅拷贝
copy函数时浅拷贝,只对可变类型的第一层对象进行拷贝
对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象
4.1、可变类型浅拷贝
#普通赋值
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=c
print(id(d))
print(id(c))
#浅拷贝可变类型
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(d))
print(id(c))
#浅拷贝、深层数据
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))
#浅拷贝不可变类型
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))
4.2、深拷贝
对每一层拷贝对象都会开辟新的内存空间进行存储
# 深拷贝,可变数据
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.deepcopy(c)
# print(id(a))
print(id(c))
print(id(d))
# 深拷贝,深层数据
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.deepcopy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))
#深拷贝不可变类型
import copy
a =(1,2,3)
b=(11,22,33)
c =(a,b)
d=copy.deepcopy(c)
print(id(c))
print(id(d))
5、函数参数
作用:1、函数名存放的是函数所在空间的地址
2、函数名()执行函数名所存放空间地址中的代码
3、如下func01=func02函数名可以像普通变量一样赋值,func01()等价于func0()
def func01():
print("func01 is show")
def foo(func):
func()
foo(func01)
6、闭包
6.1、闭包作用:
闭包可以保存函数内的变量,不会随着函数调用完而销毁
6.2、闭包的定义
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数成为闭包。
6.3、构成闭包的条件
1、在函数嵌套
2、内部函数使用了外部函数的变量
3、外部函数返回了内部函数
6.4、闭包的使用
def config_name(name):
def say_info(info):
print(name + ":" , info)
return say_info
tom =config_name("tom")
tom("你好")
tom("你在么")
jerry = config_name("jerry")
jerry("你好")
jerry("我在呢")
6.5、修改闭包
修改闭包内使用的外部变量使用nonlocal关键字完成
def func_out(num1):
def func_inner(num2):
nonlocal num1
num1 = num2 + 10
print(num1)
func_inner(10)
print(num1)
return func_inner
f=func_out(10)
f(10)
7、装饰器
7.1、装饰器的作用
在不改变原有函数的源代码的情况下,给函数增加新的功能
装饰器符合了开发中的封闭原则
本质上相当于是一个闭包
装饰器的语法格式
def check(fn):
def inner():
print("登录验证。。。。")
fn()
return inner
#解释器遇到@check 会立即执行comment = check(comment)
@check
def comment():
print("发表评论")
#comment = check(comment)
comment()
7.2、装饰器的使用
使用场景:函数执行时间统计
import time
def get_time(fn):
def inner():
start = time.time()
fn()
end = time.time()
print("时间:",end-start)
return inner
@get_time
def func():
for i in range(10000):
print(i)
func()
装饰器作用:在不改变已有函数源代码及调用方式的前提下,对已有函数进行功能的扩展
7.3、通用装饰器——带有参数的函数
def logging(fn):
def inner(a,b):
fn(a,b)
return inner
@logging
def sum_num(a,b):
result = a + b
print(result)
sum_num(1,2)
7.4、装饰带有返回值的函数
def logging(fn):
def inner(a,b):
result=fn(a,b)
return result
return inner
@logging
def sum_num(a,b):
result = a + b
return result
result = sum_num(1,2)
print(result)
7.5、装饰带有不定长参数的函数
def logging(fn):
def inner(*args, **kwargs):
fn(*args, **kwargs )
return inner
@logging
def sum_num(*args, **kwargs):
print(args,kwargs)
sum_num(1, 2,3,age=18)
7.6、多个装饰器
def check1(fn1):
def inner1():
print("登录验证")
fn1()
return inner1
def check2(fn2):
def inner2():
print("登录验证2")
fn2()
return inner2
@check2
@check1
def comment():
print("发表评论")
comment()
离函数最近的装饰器先装饰,然后外面的装饰器再装饰,由内到外的装饰过程
7.7、带有参数的装饰器
使用装饰器装饰函数的时候可以传入指定参数
语法:@装饰器(参数。。。。)
def logging(flag):
def decorator(fn):
def inner(num1,num2):
if flag == "+":
print("正在努力加法计算")
elif flag == "-":
print("正在努力减法计算")
result = fn(num1,num2)
return result
return inner
return decorator
@logging('+')
def add(a,b):
result = a+b
return result
result = add(1,3)
print(result)
带参数的装饰器
1、装饰器的外部函数只接受一个参数—被装饰的函数
2、需要给装饰器传参数需要在装饰器外部再增加一个函数
7.8、类装饰器
__ call __ 方法的使用
一个类里面一旦实现了 __ call __ 方法
那么这个类创建的对象就是一个可调用对象,可以像调用函数一样进行调用
class Check(object):
def __init__(self,fn):
self._fn = fn
def __call__(self, *args, **kwargs):
print("我是call方法")
self._fn()
@Check
def comment():
print("发表评论")
comment()