zoukankan      html  css  js  c++  java
  • python item repr doc format slots doc module class 析构 call 描述符

    1.item

    # __getitem__ __setitem__ __delitem__    obj['属性']操作触发
    
    class Foo:
        def __getitem__(self, item):
            return self.__dict__[item]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            self.__dict__.pop(key)
    
    f = Foo()
    f.name = 'zq'
    f.age = 123
    print(f.__dict__)
    
    del f.name
    print(f.__dict__)
    
    print(f.age)

    2.str repr

    class Foo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return "定制__str__ %s %s" %(self.name,self.age)
    
        def __repr__(self):
            return "定制的__repr__ 替换__str__"
    
    
    f = Foo("zhangsan","12")
    
    # 改变对象的字符串显示
    # __str__
    # __repr__ 在解释器中触发 当和str同时存在执行str,当str不存在,执行repr,是str的替代者
    # str(f) > f.__str__()> "定制__str__"
    print(f)  # 定制__str__ zhangsan 12

    3.format定制

    # 自定制 format
    class Date:
        def __init__(self, year, month, day):
            self.year = year
            self.month = month
            self.day = day
    
        def __format__(self, format_spec=""):
            return "{0.year}{format_spec}{0.month}{format_spec}{0.day}".format(self, format_spec=format_spec)
    
    
    d1 = Date('2018', '12', '12')
    print(format(d1))  # 20181212
    print(format(d1, ':'))  # 2018:12:12

    4.slot 类变量

    # __slots__ 是一个类变量 可以是list tunple iter...
    # 减少内存使用 取代__dict__的属性 不再有__dict__
    # 1.限制创建属性
    class Foo:
        __slots__ = ['name', 'age']  # 类似属性字典 定义字典中key {'name':None,'age':None}
    
    
    f1 = Foo()
    f1.name = 'zhangsan'
    f1.age = 100
    # print(f1.__dict__)  # AttributeError: 'Foo' object has no attribute '__dict__'
    print(f1.__slots__)  # ['name', 'age']
    print(f1.name, f1.age)
    # f1.gender = 'man' # AttributeError: 'Foo' object has no attribute 'gender'

    5.doc

    # __doc__ 文档注释 改属性不可被继承
    class Foo:
        '''
        我是Foo文档信息
        '''
        pass
    
    
    class A(Foo):
        '''
        我是A文档信息
        '''
        pass
    
    
    print(Foo.__doc__)  # 我是Foo文档信息
    print(A.__doc__)  # 我是A文档信息

    6.module class

    # __module__ 查看由那个module产生
    # __class__ 查看由那个类产生
    import c c = c.c() print(c.name) print(c.__module__) print(c.__class__)

    7.析构方法 __del__ 当对象在内存中被释放时,自动触发执行

    # __del__ 析构函数 删除实例才触发该函数
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def __del__(self):
            print("__del__ 实例")
    
    
    f1 = Foo('zhangsan')
    del f1.name  # 先删除实例的属性 再执行下面语句 然后删除实例 执行析构函数
    print("--------->")

    8.call方法

    # call 对象后面加(),触发执行
    # call 类()执行 会触发__call__ 函数 Foo()
    class Foo:
        def __call__(self, *args, **kwargs):
            print("触发实例 obj()")
    
    
    f1 = Foo()
    f1()
    Foo()

    9.迭代器协议 next iter

    # 迭代器协议:对象必须有一个next方法,执行一次返回迭代下一项,直到Stopiteration,
    # __iter___ 把一个对象变成可迭代对象
    class Foo:
        def __init__(self, age):
            self.age = age
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.age == 197:
                raise StopIteration("end")
            self.age += 1
            return self.age
    
    
    f1 = Foo(195)
    print(f1.__next__())
    print(f1.__next__())
    # print(f1.__next__())
    
    for i in f1:  # for循环调用f1中的iter方法变成可迭代对象 再执行next方法 iter(f1)==f1.__iter__()
        print(i)
    
    # 斐波那契数列
    class Fib:
        def __init__(self, num):
            self._x = 1
            self._y = 1
            self.num = num
    
        def __iter__(self):
            return self
    
        def __next__(self):
            self._x, self._y = self._y, self._x + self._y
            if self._x > self.num:
                raise StopIteration("结束")
            return self._x
    
        def show_fib(self):
            l = []
            for i in self:
                l.append(i)
            return l
    
    #求1000内的数
    f1 = Fib(100000)
    print(f1.show_fib())

    10.描述符

    描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
    __get__():调用一个属性时,触发
    __set__():为一个属性赋值时,触发
    __delete__():采用del删除属性时,触发

    #描述符Str
    class Str:
        def __get__(self, instance, owner):
            print('Str调用')
        def __set__(self, instance, value):
            print('Str设置...')
        def __delete__(self, instance):
            print('Str删除...')
    
    #描述符Int
    class Int:
        def __get__(self, instance, owner):
            print('Int调用')
        def __set__(self, instance, value):
            print('Int设置...')
        def __delete__(self, instance):
            print('Int删除...')
    
    class People:
        name=Str()
        age=Int()
        def __init__(self,name,age): #name被Str类代理,age被Int类代理,
            self.name=name
            self.age=age
    
    #何地?:定义成另外一个类的类属性
    
    #何时?:且看下列演示
    
    p1=People('alex',18)
    
    #描述符Str的使用
    p1.name
    p1.name='egon'
    del p1.name
    
    #描述符Int的使用
    p1.age
    p1.age=18
    del p1.age
    
    #我们来瞅瞅到底发生了什么
    print(p1.__dict__)
    print(People.__dict__)
    
    #补充
    print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的
    print(type(p1).__dict__ == People.__dict__)
    
    描述符应用之何时?何地?

    注意事项:
    一 描述符本身应该定义成新式类,被代理的类也应该是新式类
    二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
    三 要严格遵循该优先级,优先级由高到底分别是
    1.类属性
    2.数据描述符
    3.实例属性
    4.非数据描述符
    5.找不到的属性触发__getattr__()

     11.开发规范

    # 软件开发规范 范例
    '''
    bin             脚本文件
        start.py    启动文件
    
    conf
        settings.py 配置文件
    
    db              用户数据
        admin
        classes
        teacher
        course
        cource_to_school
        student
    
    lib            公共类库
        commons.py 
    
    log            日志信息
    
    src或core            核心文件         
    
    #导入模块
    # BASER_DIR
    import sys, os
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)

    参考:http://www.cnblogs.com/linhaifeng/articles/6204014.html

  • 相关阅读:
    Delphi中WebBrowser自动填表模板
    对TMemoryStream的一些改进(用到了LockFile)
    用Delphi画圆角Panel的方法(使用CreateRoundRectRgn创造区域,SetWindowRgn显示指定区域)
    Delphi5的System.pas只有11514行
    《MFC游戏开发》笔记八 游戏特效的实现(二):粒子系统
    Delphi动态申请数组内存的方法(不使用SetLength,采用和C相似的方式)
    Delphi的类型转换 good
    New 和 GetMem 的不同之处
    XML SelectSingleNode的使用 根据节点属性获取该节点
    ADO面板上的控件简介
  • 原文地址:https://www.cnblogs.com/icemonkey/p/10457935.html
Copyright © 2011-2022 走看看