Pthon面向对象-补充知识

        Pthon面向对象-补充知识

                       作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

 

一.tracemalloc

标准库tracemalloc,可以统计内存使用情况,通过下面的案例可以看出内存使用上字典还是较为占用空间的。
 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 import tracemalloc
 7 
 8 tracemalloc.start()         #开始跟踪内存分配
 9 
10 d = [dict(zip("xy",(5,6))) for i in  range(1000000)]      #237M
11 
12 t = [tuple(zip("xy",(5,6))) for i in range(1000000)]      #191M
13   
14 snapshot = tracemalloc.take_snapshot()      #快照,当前内存分配
15 
16 top_stats = snapshot.statistics("lineno")   #快照对象的统计
17 
18 
19 for stat in top_stats:
20     print(stat)
21     
22     
23     
24 #以上代码执行结果如下:
25 D:/Language/Python/Code/Devops/Python基础/07.面向对象编程/魔术方法/13.补充知识.py:10: size=237 MiB, count=1999995, average=124 B
26 D:/Language/Python/Code/Devops/Python基础/07.面向对象编程/魔术方法/13.补充知识.py:12: size=191 MiB, count=3000002, average=67 B
27 D:/Language/Python/Code/Devops/Python基础/07.面向对象编程/魔术方法/13.补充知识.py:14: size=432 B, count=1, average=432 B
28 D:\Language\Python\interpreter\Python37\lib\tracemalloc.py:532: size=64 B, count=1, average=64 B

 

二.__slots__

应用场景:
  使用需要构建在数百万以上众多对象,且内存容量较为紧张,实例的属性简单,固定且不用动态增加的场景。
  可以使用tracemalloc看看内存使用的差异。建议使用stats = snapshot.statistics("filename")查看总内存使用。
 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 class A:
 7     x = 100
 8 
 9     """
10         "__slots__"魔术方法会告诉解释器,实例的属性都叫上面,一般来说,既然要节约内存,最好还是使用元组比较好。
11         一旦提供了"__slots__",就阻止实例产生"__dict__"来保存实例的属性。
12     """
13     __slots__ = ("y","z")
14 
15     def __init__(self):
16         self.y = 20
17         self.z = 30
18 
19     def show(self):
20         print(self.x,self.y)
21 
22 class B(A):     #B类继承自A类
23     pass
24 
25 a = A()
26 a.show()
27 # a.name = "tom"      #会抛异常"AttributeError: 'A' object has no attribute 'name'",说明实例不可以动态增加属性了,因为属性已经被"__slots__"提前定义好啦!
28 
29 A.name = "Tom"        #这是可以的,因为这个是类属性,说明"__slots__"只能限制当前实例而不能限制当前类
30 
31 print(A.name)
32 print("A",A.__dict__)
33 print("B",B().__dict__)     #可以访问B类实例的"__dict__"属性,说明"__slots__"不影响类实例,不会继续下去,除非子类里面自己也定义了"__slots__"
34 # print(a.__dict__)         #抛异常"AttributeError: 'A' object has no attribute '__dict__'",一旦提供了"__slots__",就阻止实例产生"__dict__"来保存实例的属性。
35 print(a.__slots__)
36 
37 
38 
39 #以上代码执行结果如下:
40 100 20
41 Tom
42 A {'__module__': '__main__', 'x': 100, '__slots__': ('y', 'z'), '__init__': <function A.__init__ at 0x00000157A5B05678>, 'show': <function A.show at 0x00000157A5B051F8>, 'y': <member 'y' of 'A' objects>, 'z': <member 'z' of 'A' objects>, '__doc__': None, 'name': 'Tom'}
43 B {}
44 ('y', 'z')

 

三.未实现和未实现异常

 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 print(type(NotImplemented))
 7 print(type(NotImplementedError))
 8 
 9 print(NotImplemented)           #是个值,单值,是"NotImplementedType"类的实例
10 
11 
12 raise NotImplementedError      #是类型,是异常类,返回type
13 
14 
15 
16 #以上代码执行结果如下:
17 <class 'NotImplementedType'>
18 <class 'type'>
19 NotImplemented
20 Traceback (most recent call last):
21   File "D:/Language/Python/Code/Devops/Python基础/07.面向对象编程/魔术方法/13.补充知识.py", line 12, in <module>
22     raise NotImplementedError      #是类型,是异常类,返回type
23 NotImplementedError

 

四.运算符重载中的反向方法

 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 class A:
 7     def __init__(self,x):
 8         self.x = x
 9 
10     def __add__(self, other):
11         print(self,"add")
12         return self.x + other.x
13 
14     def __iadd__(self, other):
15         print(self,"iadd")
16         return A(self.x + other.x)
17 
18     def __radd__(self, other):
19         print(self,"radd")
20         return self.x + other.x
21 
22 class B:
23     def __init__(self,x):
24         self.x = x
25 
26     """
27         如果不实现"__add__"方法,其实B类也等价于下面注释的代码
28     """
29     # def __add__(self, other):
30     #     if isinstance(other,type(self)):
31     #         return self.x + other.x
32     #     else:
33     #         return NotImplemented
34 
35 a = A(10)
36 b = A(20)
37 print(a,b)
38 print(a + b)    #调用"__add__"方法
39 print(b + a)
40 b += a          #调用"_iadd__"方法
41 a += b          #同上
42 
43 c = B(30)
44 print(a + c)
45 print(c + a)            #这里的c是类B的实例,但是类B没有实现"__add__"方法,就去找a的"_radd__"方法
46 # print(a + "abc")      #报错"AttributeError: 'str' object has no attribute 'x'",字符串实现了"__add__"方法,不过默认是处理不了和其它类型的加法,就返回"NotImplemented"
47 # print(1 + a)          #报错"AttributeError: 'int' object has no attribute 'x'",整型也实现了"__add__"方法的,不过这个方法对于这种加法的返回值是"NotImplemented",解释器发现在这个值,就会发起第二操作对象的"__radd__"方法的调用。
48 
49 
50 
51 #以上代码执行结果如下:
52 <__main__.A object at 0x000001DFBE585908> <__main__.A object at 0x000001DFBE585988>
53 <__main__.A object at 0x000001DFBE585908> add
54 30
55 <__main__.A object at 0x000001DFBE585988> add
56 30
57 <__main__.A object at 0x000001DFBE585988> iadd
58 <__main__.A object at 0x000001DFBE585908> iadd
59 <__main__.A object at 0x000001DFBE585A48> add
60 70
61 <__main__.A object at 0x000001DFBE585A48> radd
62 70

 

五.仅位置参数

 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 """
 7     2019年10月14日,发布了Python3.8.0,提供了仅位置参数(Positional-only arguments)。
 8 """
 9 
10 
11 def add(x, y=5, /, z=6):
12     print(x + y + z)
13 
14 
15 add(1, 2, 3)
16 add(1, y=2, z=3)
17 add(x=1, y=2, z=3)
18 add(1, 3, z=5)

 

六.Python的对象模型

在Python中,任何对象都有类型,可以使用type()或者 __class__ 查看。
但是类型也是对象即类对象,它也有自己的类型。
所有新类型的缺省类型是type(可以使用元类来改变)
特殊类型type是所有对象的缺省类型,也包括type自己。但它又是一个对象,因此从object继承特殊类型object是继承树的顶层,它是python所有类型的最终基类
也就是说,继承都来自object,类型都看type。type也是对象继承自object,object也有类型是type。 这俩又特殊,type类型是它自己,object没有基类。
 

 

七.断言语法

 1 #!/usr/bin/env python
 2 #_*_conding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie
 5 
 6 a = 100
 7 
 8 assert a > 80,"对变量a进行断言,即如果a大于80则条件成立不做任何处理,否则抛出异常"
 9 
10 print("{0} 我是分隔符 {0}".format("*" * 30))
11 
12 assert a < 100,"对变量a进行断言,即如果a小于100则条件成立不做任何处理,否则抛出异常"

 

posted @ 2019-11-05 22:35  尹正杰  阅读(298)  评论(0编辑  收藏  举报