liangzhiwen

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
抽象基类(了解)

- 说明:
  - 抽象基类就是为了统一接口而存在的
  - 它不能进行实例化
  - 继承自抽象类的子类必须实现抽象基类的抽象方法
- 示例:
      from abc import ABC, abstractmethod
      
      # 抽象基类
      class Animal(ABC):
          # 定义抽象方法:规定接口
          @abstractmethod
          def run(self):
              pass   
          
      # 抽象基类不能实例化
      # a = Animal()
      
      class Cat(Animal):
          # 必须实现基类中规定的抽象方法,才能实例化
          def run(self):
              print('猫喜欢走猫步')
              
      c = Cat()

内置函数

- 构造和析构
      __init__、__del__
- 属性操作    
      __getattr__、__setattr__、__delattr__
- 支持字典操作
      __getitem__、__setitem__、__delitem__
- 像函数一样调用
      __call__
- 打印输出
      __str__
- 对象的字符串表示
        class Person:
            def __init__(self, name, age):
                self.name = name
                self.age = age
      
            # print/str都会自动触发该方法
            def __str__(self):
                print('__str__')
                return '姓名:{},年龄:{}'.format(self.name, self.age)
      
            # 通常用来返回对象的字符串表示形式
            # 调用repr方法时会自动触发
            def __repr__(self):
                return 'Person("{}", {})'.format(self.name, self.age)
              
              
      	xiaoming = Person('小明', 20)
          # print(xiaoming)
          # s = str(xiaoming)
          # print(s)
      
          r = repr(xiaoming)
          print(r)
          # eval:可以指向有效python字符串
          x = eval(r)
          print(x)
          print(type(x))       

- 算术运算符重载
  - 示例
        class Number:
            def __init__(self, num):
                self.num = num
      
            def __str__(self):
                return str(self.num)
      
            # 对象出现在'+'的左边时自动触发
            def __add__(self, other):
                print('__add__')
                return self.num + other
      
            # 对象出现在'+'的右边时自动触发
            def __radd__(self, other):
                return self.num + other
      
            # +=运算时会自动触发,若没有则会调用__add__方法
            def __iadd__(self, other):
                return Number(self.num + other)
              
      n = Number(10)
      # ret = n + 10
      # ret = 20 + n
      n += 50 # n = n + 50
      print(n)
      
  - 自行测试
      加法:__add__、__radd__、__iadd__
      减法:__sub__、__rsub__、__isub__
      乘法:__mul__、__rmul__、__imul__
      除法:__truediv__、__rtruediv__、__itruediv__
      求余:__mod__、__rmod__、__imod__
- 关系运算符重载
        class Number:
            def __init__(self, num):
                self.num = num
      
            # 大于:>
            def __gt__(self, other):
                return self.num > other
      
            # 小于:<
            def __lt__(self, other):
                return self.num < other
      
            # 等于,==会触发,不实现__ne__时,!=也会触发该方法
            def __eq__(self, other):
                print('__eq__')
                return self.num == other
      
            # 大于等于:>=
            def __ge__(self, other):
                return self.num >= other
      
            # 小于等于:<=
            def __le__(self, other):
                return self.num <= other
      
            # 不等于:!=
            def __ne__(self, other):
                return self.num != other
          
      n = Number(20) 
      print(n > 10)
      print(n < 10)
      print(n != 10)

内存管理

- 引用计数
  - python中所有的变量都是通过对象完成的,对象的管理时通过引用计数解决的。
  - 当创建一个对象赋值给一个变量时,引用为1,当多一个变量指向对象时,计数值加1;当少一个变量指向对象时,计数值减1,减到0时调用对象__del__方法,释放对象相关资源
  - 不可变变量的引用计数值是没有意义的
  - 通过函数sys.getrefcount(lt)可以查看对象的引用计数,该函数本身会对对象的引用计数加1
- 函数传参
  - 对不可变的变量来说,传递的值,函数中不会改变传递进来的变量。
  - 对于可变对象、自定义对象来说,传递的是引用,函数中操作的就是原对象。
  - 示例:
      def test(n):
            n += 10
            
      num = 2
      test(num)
      print(num)
      
      def test2(lt):
      	lt[0] = 20
      	
      lt = [1, 2, 3]
      test2(lt)
      print(lt)

- 深浅拷贝
  - 不可变的类型不存在深浅拷贝
  - 浅拷贝只会拷贝对象本身,其中的元素只会增加引用
  - 深拷贝不但会拷贝对象本身,还会对其中的元素进行拷贝
  - 示例:  
      import copy
      
      lt = [[1, 11], 2, 3]
      # lt2 = lt
      # 浅拷贝:只拷贝对象本身,里面的元素只增加引用
      # lt2 = lt.copy()
      # 浅拷贝
      # lt2 = copy.copy(lt)
      # 深拷贝:拷贝对象本身,对象中的元素也进行拷贝
      lt2 = copy.deepcopy(lt)
      lt2[0] = 100
      print(id(lt))
      print(id(lt2))
      
      # 判断是否是同一对象的引用
      print(lt is lt2)
      print(lt)

数据持久化存储

- 说明:持久化存储方案,普通文件、数据库、序列化
- 示例:
      import pickle
      
      class Person:
          def __init__(self, name, age):
              self.name = name
              self.age = age
      
          def __str__(self):
              return 'name:{},age:{}'.format(self.name, self.age)
          
          
      xiaoming = Person('xiaoming', 20)
      
      # 序列化,会将对象转换为bytes
      # s = pickle.dumps(xiaoming)
      # print(s)
      
      # 从字节流中加载转换为对象
      # xm = pickle.loads(s)
      # print(xm)
      # print(type(xm))
      
      # 直接保存到文件中
      # fp = open('data.txt', 'wb')
      # pickle.dump(xiaoming, fp)
      
      # 从文件中读取对象
      fp = open('data.txt', 'rb')
      xm = pickle.load(fp)
      print(xm)
      print(type(xm))

 

posted on 2018-09-10 10:57  liangzhiwen  阅读(108)  评论(0编辑  收藏  举报