zoukankan      html  css  js  c++  java
  • 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:LanguagePythoninterpreterPython37lib	racemalloc.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则条件成立不做任何处理,否则抛出异常"
  • 相关阅读:
    RN的win7开发环境部署和问题解决
    Android EditText弹出软键盘实现页面标题头不动,软键盘弹出在编辑框下面
    android打包生成apk时自定义文件名版本号。自定义项目字段等等
    Android ConstraintLayout 约束布局属性
    AS基本设置
    PermissionUtils
    kotlin之字符串模板
    kotlin之字符串
    kotlin之数组
    kotlin之布尔类型
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11802229.html
Copyright © 2011-2022 走看看