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

 

posted @ 2019-03-01 17:54  风追海浪  阅读(231)  评论(0编辑  收藏  举报