property的作用:相当于把方法进行了封装,开发者在对属性设置数据的时候更方便
class Money(object):
def __init__(self):
self.__money = 0
@property
def money(self):
return self.__money
@money.setter
def money(self,value):
if isinstance(value,int):
self.__money = value
else:
print("error:不是整型数字")
迭代器
1.可迭代对象
直接作用于for循环的数据类型有以下几种:
一种是集合数据类型,如list,tuple,dict,set,str等;
一种是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:lterable。
2.判断是否可以迭代
可以使用isinstance()判断一个对象是否是lterable:
from collections import Iterable
isinstance("abc",Iterable)
>>>True
3.迭代器
可以被next()函数调用并不断返回下一值的对象成为迭代器:Iterator
from collections import Iterator
isinstance([],Iterator)
>>>False
isinstance((x for x in range(10)),Iterator)
>>>True
4.iter()函数
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
isinstance(iter([]),Iterator)
>>>True
闭包
#在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
def test(number):
print("----1------")
def test_in(number2):
print("------2----")
print(number-number2)
print("-----3-----")
return test_in
ret = test(100)
ret(1)
\>>>----1------
-----3-----
------2----
99
def test(a,b):
def test_in(x):
print(a*x+b)
return test_in
line1 = test(1,1)
line1(0)
line2 = test(10,4)
line2(0)
line1(0)
装饰器
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
innerFunc = w1(f1)
innerFunc()
f1 赋值地址,f1()调用函数
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
f1 = w1(f1)
f1()
@w1等价于w1(f1)
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
@w1
def f1():
print("----f1-----")
@w1
def f2():
print("----f2-----")
f1()
f2()
多个装饰器
def makeBold(fn):
def wrapped():
print("----1------")
return "" + fn() + ""
return wrapped
def makeItalic(fn):
def wrapped():
print("----2------")
return "" + fn() +""
return wrapped
@makeBold#只要python解释器执行到了这个代码,那么就会自动进行装饰,而不是等到调用才装饰的
@makeItalic
def test3():
print("--------3-----")
return "hello world-3"
ret = test3()
print(ret)
>>>----1------
----2------
--------3-----
hello world-3
从上往下执行,从下往上装饰
def w1(func):
print("----正在装饰1-----")
def inner():
print("------正在验证权限1-----")
def w2(func):
print("---- 正在装饰2-----")
def inner():
print("----正在验证权限2----")
func()
return inner()
@w1
@w2
def f1():
print("----f1----")
f1() #在调用f1之前,已经进行装饰了
>>>---- 正在装饰2-----
----正在装饰1-----
------正在验证权限1-----
----正在验证权限2----
----f1----
装饰器对有参数,无参数函数进行装饰
def func(functionName):
print("----func---1---")
def fun_in(*args,**kwargs):#定义不定长参数
print("---func_in---1---")
functionName(*args,**kwargs)
print("---func_in---2---")
print("---func---2---")
return func_in
@func
def test1(a,b,c):
print("----test-a=%d,b=%d,c=%d---"%(a,b,c))
@func
def test2(a,b,c,d):
print("----test-a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d))
test1(11,22,33)
test2(44,55,66,77)
\>>>----func---1---
---func---2---
---func---1---
---func---2---
---func_in---1---
----test-a=11,b=22,c=33---
---func_in---2---
---func_in---1---
----test-a=44,b=55,c=66,d=77---
---func_in---2---
装饰器对带有返回值的参数进行装饰
def func(functionName):
print("---func---1---")
def func_in():
print("---func_in---1---")
ret = functionName()#保存返回来的haha
print("---func_in---2---")
return ret #把haha返回到调用处
print("---func---2---")
@func
def test():
print("----test----")
return "haha"
ret = test()
print("test return value is %s"%ret)
带有参数的装饰器
def func_arg(arg):
def func(functionName):
def func_in():
print("---记录日志-arg=%s--"%arg)
if arg =="heihei":
functionName()
functionName()
else:
functionName()
return func_in()
return func
@func_arg("heihei")#带有参数的装饰器,能够起到在运行时,有不同的功能
def test():
print("--test--")
@func_arg("haha")
def test2():
print("--test2--")
test()
test2()
作用域
LEGB规则
locals -> enclosing function -> globals -> builtings
locals:当前所在命名空间
enclosing function:外部嵌套函数的命名空间(闭包中常见)
globals:全局变量
builtings:内嵌
动态添加属性和方法
添加属性 类/实例.属性 = XX
添加方法 不能按上面方法,
import types.MethodType
绑定的对象.函数名() = types.MethodType(函数名,绑定的对象)
_slots_
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量来限制class实例能添加的属性:
>>>class Person(object):
__slots__ = ("name","age")
>>>P = Person()
>>>P.name = "老王"
>>>P.age = 20
#添加其他属性会报错
生成器
一边循环一边计算
创建生成器方法
1.把列表生成式的[]改成(),通过next函数获取生成器的下一个返回值
def creatNum():
print("-----start-----")
a,b = 0,1
for i in range(5):
print("----1----")
yield b #程序停下来,把yield后面的值返回
print("----2----")
a,b = b,a+b
print("----3----")
print("----stop----")
\>>>a = creatNum()
\>>>a
\>>>next(a)
-----start-----
----1----
1
\>>>next(a)#等价于a.__next__()
----2----
----3----
----1----
1
def test():
i = 0
while i<5:
temp = yield i
print(temp)
i+=1
\>>>t = test()
\>>>t.__next__()
[out] 0
\>>>t.__next__()
None
[out] 1
\>>>t.__next__()
None
[out] 2
\>>>t.send("haha")
haha
[out] 3
类当作装饰器
定义一个__call__方法,类就可以直接调用