java转python记录 六

生成器的使用    把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__)

对于有参数的装饰器:

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")

偏函数:参数放一半的一个新函数,需要结合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)

__slots__    此属性限定了类的属性有哪些,不在这个里面的属性无法添加成功,在继承的时候,子类找完找父类父类,子类没有就不管

class Person(object):
    # 如何限制实例属性,仅允许有某几个方法或属性 该怎么办?
    __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)

使用type创建class对象,要创建一个class对象,type()函数依次传入3个参数:

  1. class的名称;
  2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
  3. 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)

使用元类创建简单的orm框架

比较神奇的是python的文档注释,可以运行注释中的代码

上一篇            下一篇

猜你喜欢

转载自blog.csdn.net/livelse/article/details/80840177