生成器的使用 把yield换成print即可,记住它是循环的每次都有新的状态
装饰器的作用 spring中的拦截器一样的功能,语法比较特殊,定义一个方法就能用@+方法名,操作了
import functools
def log(func):
@functools.wraps(func)
def wrapper(*arg1,**arg2):
print("方法:%s" % func,arg1,arg2)
ret = func(*arg1, **arg2)
print("方法:%s 执行后" % func)
return ret
# wrapper.__name__ = func.__name__
# #不推荐这么写,使用@functools.wraps(func)来操作
return wrapper
@log #加了此注解之后相当于执行了这样的代码 myplus = log(myplus)
def myplus(x,y):
print(x + y)
print(myplus.__name__)
@functools.wraps(func)
def wrapper(*arg1,**arg2):
print("方法:%s" % func,arg1,arg2)
ret = func(*arg1, **arg2)
print("方法:%s 执行后" % func)
return ret
# wrapper.__name__ = func.__name__
# #不推荐这么写,使用@functools.wraps(func)来操作
return wrapper
@log #加了此注解之后相当于执行了这样的代码 myplus = log(myplus)
def myplus(x,y):
print(x + y)
print(myplus.__name__)
对于有参数的装饰器:
def logger(para):
def log(func):
@functools.wraps(func)
def wrapper(*args1,**args2):
print("方法进入前"+para)
ret = func(*args1,**args2)
print("方法执行后" + para)
return ret
return wrapper
return log
@logger("here") #加了此注解之后相当于执行了这样的代码 myTest = logger("here")(myTest)
def myTest():
print("myTest")
#加了此注解之后相当于执行了这样的代码 myTest = logger("here")(myTest)
def myTest():
print("myTest")
偏函数:参数放一半的一个新函数,需要结合functools模块下的partition方法实现
myPart = functools.partial(myplus,y=20) #类似于只调用了myplus一半的参数,还有一半参数在下一行调用
myPart(100)
type(p)==Person 函数可以返回参数的类型
from types import MethodType
class Person(object):
pass
#动态添加实例方法
def main():
s1 = Person()
s2 = Person()
def tell(q):
print("hello")
s1.tell = MethodType(tell,s1) #这种方式可以有
s1.say = tell #这个也是可以的,他们在参数上不一样
s1.tell()
s1.say(1)
Person.gua = tell #给类上重新绑定方法
s1.gua()
s2.gua()
Person.gua(1)
#这种方式可以有
s1.say = tell #这个也是可以的,他们在参数上不一样
s1.tell()
s1.say(1)
Person.gua = tell #给类上重新绑定方法
s1.gua()
s2.gua()
Person.gua(1)
__slots__ 此属性限定了类的属性有哪些,不在这个里面的属性无法添加成功,在继承的时候,子类找完找父类父类,子类没有就不管
class Person(object):
# 如何限制实例属性,仅允许有某几个方法或属性 该怎么办?
__slots__ = ['name','age','tell']
pass
# 如何限制实例属性,仅允许有某几个方法或属性 该怎么办?
__slots__ = ['name','age','tell']
pass
@property装饰器的使用,可以不用声明类的实例变量,直接用此装饰器操作属性
class Man(object):
# __slots__ = ['name']
@property
def name(self):
return self._name
@name.setter #如果没有此方法,则name属性为只读属性
def name(self, value):
self._name = value
__str__和__repr__的用法,以及__getattr__结合使用的案例,见下文
class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
__repr__ = __str__
print(str(Chain().www.baidu.com)) #顺利的把属性转换为字符串类型
#顺利的把属性转换为字符串类型
枚举类型的使用
from enum import Enum
#方式一 缺点:格式不好看,不能绑定值
month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
print(month.Jan)
#方式二 缺点:需要编写代码量较大
from enum import unique
@unique #此左右可以防止枚举值的重复
class Weekday(Enum): #继承Enum类来实现
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 1
Wed = 3
Thu = 4
Fri = 5
Sat = 6
print(Weekday.Mon)
print(Weekday.Mon.value)
缺点:格式不好看,不能绑定值
month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
print(month.Jan)
#方式二 缺点:需要编写代码量较大
from enum import unique
@unique #此左右可以防止枚举值的重复
class Weekday(Enum): #继承Enum类来实现
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 1
Wed = 3
Thu = 4
Fri = 5
Sat = 6
print(Weekday.Mon)
print(Weekday.Mon.value)
使用type创建class对象,要创建一个class对象,type()
函数依次传入3个参数:
- class的名称;
- 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
- class的方法名称与函数绑定,这里我们把函数
fn
绑定到方法名hello
上。
Woman = type("Woman",(object,), {"name": "如花", "age": 10})
w = Woman()
print(w.name)
元类 Metaclass 元类和类和实例的关系,实例是类的实例化对象,类是元类的实例化对象
class MyMetaclass(type):pass 元类的父类是type而不是object
class MyMetaclass(type):
def __new__(cls, name, bases, attrs):
def test(self):
print("test")
attrs["test"] = test # 给类添加属性
# ret = type.__new__(cls, name, bases, attrs) #类添加静态属性
# ret.test = test
# return ret
return type.__new__(cls, name, bases, attrs)
type):
def __new__(cls, name, bases, attrs):
def test(self):
print("test")
attrs["test"] = test # 给类添加属性
# ret = type.__new__(cls, name, bases, attrs) #类添加静态属性
# ret.test = test
# return ret
return type.__new__(cls, name, bases, attrs)
使用元类创建简单的orm框架
比较神奇的是python的文档注释,可以运行注释中的代码