• [python] Pythonic语法笔记


    Pythonic语法笔记

    __new__

    在类实例化之前执行的,也就是在init之前执行,可以为这个类写操作。接受的参数不是self而是cls。只有在new方法里返回类才会执行init操作,需要返回父类的new。

    class A(object):
    	def __new__(cls,name):
            print("cls name:{}".format(name))
            return super().__new__(cls)
        def __init__(self,name):
            print("self name:{}".format(name))
    if __name__ == "__main__":
        a = A("ok")
        
    '''
    cls name:ok
    self name:ok
    '''
    

    getattr和getattribute

    在查找不到属性的时候会调用__getattr__

    class A():
        def __init__(self,name):
            self.info = {
                "Name":name
            }
        def __getattr__(self,item):
            return self.info[item]
    if __name__ == '__main__':
        a = A('aa')
        print(a['Name'])
    

    __getattribute__管理的是整个类的属性访问,一般不重写,getattr实际上会在getattribute中被调用,重写了之后可能会导致整个类的崩溃,所以一般不重写。getattribute是无条件调用的,无论是否存在属性,都会被调用。

    type

    type是用来创建类的类,是元类的一种,所以我们也可以通过type函数来动态创建一个类。

    type函数有三个参数,第一个是类名,第二个是基类名,第三个是属性

    def say():
        print("something")
    User = type('user',(),{'name':'xueaoru',"say":say})
    user = User()
    print(user.name)
    user.say()
    
    '''
    xueaoru
    something
    '''
    
    
    

    实际使用过程中一般不用type直接创建类,而是使用元类,定义metaclass去创建。

    我们知道new方法是可以控制在类实例化的过程,而使用元类可以使这个过程分离,单独创建一个类去管理该类的实例化过程,这样代码分离性比较好,所以称之为metaclass。

    class MetaClass(type):
        def __new__(cls,*args,**kwargs):
            return super().__new__(cls,*args,**kwargs)
    
    class Base(metaclass=MetaClass):
        def __init__(self, *args, **kwargs):
            return super().__init__(*args, **kwargs)
    
    
    class User(Base):
        def __init__(self, name,*args, **kwargs):
            self.name = name
            return super().__init__(*args, **kwargs)
        def __str__(self):
            return "user"
    
    if __name__ == "__main__":
        user = User("aoru")
        print(user)
    

    先定义了一个MetaClass,继承了type,这里其实和直接是type区别不大,因为直接返回super,也就是让实例化的过程交给父类来做,也就是type,然后定义base类,base类的metaclass是MetaClass,所以用MetaClass来做实例化的过程,User由于继承自base类,所以查找metaclass的时候自己没有,就调用基类的metaclass。

    属性描述符

    实际上是一个用来描述属性的类,需要定义其get方法或者是set方法,可以用来做类型的检查。

    # 属性描述符类
    class IntField():
        def __set__(self,instance,value):
            if not isinstance(value,int):
                raise ValueError("int value err")
    class User():
        age = IntField()
    if __name__ == "__main__":
        user = User()
        user.age = '2'
        
    '''
    Traceback (most recent call last):
      File "/media/xueaoru/其他/ML/推荐系统入门/my_attr_desc_demo.py", line 9, in <module>
        user.age = '2'
      File "/media/xueaoru/其他/ML/推荐系统入门/my_attr_desc_demo.py", line 4, in __set__
        raise ValueError("int value err")
    ValueError: int value err
    '''
        
    

    数据查找过程,先查找类中的数据描述符对象,然后查找对象中的属性,然后查找类中或者基类中的属性,而在类中或者基类中查找的时候属性描述符优先。最后如果查找不到,就会调用类的getattr函数,没有就抛出异常。

    迭代器

    基于两个语法,next返回下一个迭代对象,__iter__返回被迭代的对象本身。

    class Myobject():
        def __init__(self,step):
            self.step = step
        def next(self):
            if self.step == 0:
                raise StopIteration
            self.step-=1
            return self.step
        def __iter__(self):
            return self
    

    则Myobject对象可被迭代。

    与生成器的不同

    生成器是使用了yield函数的,返回迭代器的函数,只能用于迭代操作。每次遇到yield时,函数会暂停病保存当前所有的运行信息,返回yield值,病在下一次执行next方法时从当前位置继续执行。调用一个生成器函数,返回的是一个迭代器对象。我们用的比较多的生成器是列表生成器,一个简单的生成器的例子:

    def fib(n):
        a,b,cnt = 1,1,0
        while True:
            if cnt > n:
                return
            yield a
            a,b,cnt = b,a+b,cnt+1
    f = fib(10)
    for ff in f:
        print(ff)
        
    '''
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    89
    '''
    
  • 相关阅读:
    [C++]C++11右值引用
    [cocos2d-x]registerScriptHandler和registerScriptTapHandler区别
    [深度探索C++对象模型]关于成员初始化列表(member initiallization list)
    [深度探索C++对象模型]memcpy和memset注意事项
    sql server isnull函数
    sql server 数据类型
    sql server SQL 服务器
    案例:按钮拖动移动
    PHP 随笔记
    laravel5 事务回滚
  • 原文地址:https://www.cnblogs.com/aoru45/p/11096251.html
Copyright © 2020-2023  润新知