面向对象在python中的实现(二)

  1. 方法相关补充

    • 私有化方法:__方法名,存储后变为_类名.__方法名

    • 内置特殊方法

      1. 生命周期方法

      2. 其他内置方法

        • 信息格式化操作:__str__方法(面向用户)、__repr__方法(面向python解释器、开发人员)

          class Person:
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          
              def __str__(self):
                  return "这个人的姓名是%s,年龄是%s"%(self.name,self.age)
          
          
          p1 = Person("sz", 11)
          print(p1)
          print(str(p1))
          
          import datetime
          
          now = datetime.datetime.now()
          print(now)# 2021-10-23 11:49:40.357769
          print(repr(now))# datetime.datetime(2021, 10, 23, 11, 49, 40, 357769)
          temp = repr(now)
          result = eval(temp)
          print(result)# 2021-10-23 11:49:40.357769
          
        • 调用操作:__call__方法

          作用:使得”对象“具备当作函数,来调用的能力

          使用:

          应用场景:

          案例:

          class PenFactory:
              def __init__(self,p_type):
                  self.type = p_type
              def __call__(self, p_color):
                  print("创建了一个%s类型的画笔,它是%s颜色"%(self.type,p_color))
          gangbiF = PenFactory("钢笔")
          gangbiF("红色")
          gangbiF("绿色")
          gangbiF("黄色")
          
        • 索引操作

          作用:可以对一个实例对象进行索引操作

          步骤:

          1. 实现三个内置方法

            class Person:
                def __init__(self):
                    self.cache = {}
                def __setitem__(self, key, value):
                    self.cache[key] = value
                def __getitem__(self, item):
                    return self.cache[item]
                def __delitem__(self, key):
                    del self.cache[key]
            p = Person()
            p["name"] = "sz"
            print(p["name"])
            del p["name"]
            print(p.cache)
            
          2. 可以以索引的形式操作对象

            • 增/改:p[1] = 999、p[“name”] = “sz”
            • 查:p[1]、p[“name”]
            • 删:del p[1]、del p[“name”]
        • 切片操作

          • python2

            1. 实现三个内置方法
              • __setspice__:设置某个元素切片时调用
              • __getspice__:获取某个元素切片时调用
              • __delspice__:删除某个元素切片时调用
            2. 可以直接按照切片的方式操作对象:p[1,6,2]
            3. 注意:过期
          • python3:统一由“索引操作”进行管理

            • def __setitem__(self,key,value)

            • def __getitem__(self,item)

            • def _delitem_(self,key)

              class Person:
                  def __init__(self):
                      self.items = [1,2,3,4,5,6,7,8]
                  def __setitem__(self, key, value):
                      if isinstance(key,slice):
                          self.items[key.start:key.stop:key.step] = value
                  def __getitem__(self, item):
                      print("getitem",item)
                  def __delitem__(self, key):
                      print("delitem",key)
              p = Person()
              p[0:4:2] = ["a","b"]
              print(p.items)
              
        • 比较操作:

          1. 作用:可以自定义对象“比较大小、相等、真假”规则

          2. 步骤:

            • 相等:__eq__
            • 不相等:_ne_
            • 小于:__lt__
            • 小于等于:__le__
            • 大于:_gt_
            • 大于等于:_ge_
            class Person:
                def __init__(self,age,height):
                    self.age = age
                    self.height = height
                def __eq__(self, other):#等于
                    return self.age == other.age
                #如果该方法没实现,则默认为eq结果反着来
                def __ne__(self, other):#不等于
                    return self.age != other.age
                def __gt__(self, other):#大于
                    pass
                def __ge__(self, other):#大于等于
                    pass
                def __lt__(self, other):#小于
                    pass
                def __le__(self, other):#小于等于
                    pass
            p1 = Person(11,111)
            p2 = Person(11,123)
            print(p1 == p2)# ==、!=、>、>=、<、<=
            
          3. 注意:

            • 如果对于反向操作的比较运算符,只定义了其中一种方法,但使用的是另外一种比较运算,那么解释器会采用调换参数的方式调用该方法。
            • 但是不支持叠加操作
          4. 补充:

            • 使用装饰器,自动生成“反向”“组合”的方法(略)

            • 上下文环境中的布尔值:__bool__

              class Person:
                  def __init__(self):
                      self.age = 20
                  def __bool__(self):
                      return self.age>=18
              p = Person()
              if p:
                  print("成年了")
              
        • 遍历操作

          1. 怎样让我们自己创建的对象可以使用for in进行遍历

            • 方式一:实现__getitem__方法

              class Person:
                  def __init__(self):
                      self.result = 1
                  def __getitem__(self, item):
                      self.result+=1
                      if self.result > 6:
                          raise StopIteration("停止遍历")
                      return self.result
              p = Person()
              for i in p:
                  print(i)
              
            • 方式二:实现__iter__方法(优先级更高)

              class Person:
                  def __init__(self):
                      self.result = 1
                  def __iter__(self):
                      print("iter")
                      #return iter([1,2,3,5])#如果是返回这个,则无需重写next方法
                      return self#将自身作为迭代器,则需要重写next方法
                  def __next__(self):
                      self.result += 1
                      if self.result >=6:
                          raise  StopIteration("停止遍历")
                      return self.result
              p = Person()
              for i in p:
                  print(i)
              
          2. 怎样让我们自己创建的对象可以使用next函数进行访问

          3. 补充

        • 描述器

          1. 概念:可以描述一个属性操作的对象

            • 对象
            • 属性的操作:增改、删、查
            • 描述
          2. 作用

          3. 定义

            • 定义一:property

              #方式一
              class Person(object):
                  def __init__(self):
                      self.__age = 18
                  def get_age(self):
                      return self.__age
                  def set_age(self,value):
                      if value <0:
                          value = 0
                      self.__age = value
                  def del_age(self):
                      del self.__age
                  age = property(get_age,set_age,del_age)
              
              p = Person()
              print(p.age)
              p.age = 30
              print(p.age)
              del p.age
              print(p.age)
              help(Person)
              
              #方式二
              class Person(object):
                  def __init__(self):
                      self.__age = 18
                  @property
                  def age(self):
                      return self.__age
                  @age.setter
                  def age(self,value):
                      self.__age = value
                  @age.deleter
                  def age(self):
                      del self.__age
              
              p = Person()
              print(p.age)
              p.age = 30
              print(p.age)
              del p.age
              print(p.age)
              
            • 定义二

              class Age:
                  def __get__(self, instance, owner):
                      print("get")
                  def __set__(self, instance, value):
                      print("set")
                  def __delete__(self, instance):
                      print("delete")
              class Person:
                  age = Age()
              
              p = Person()
              p.age = 11
              print(p.age)
              del p.age
              
          4. 调用细节

            • 使用实例进行调用(可以)
            • 使用类进行调用(不能)
            • 不能顺利转换的场景:
              • 新式类和经典类:新式类中可以生效
              • 方法拦截
                1. 一个实例属性的正常访问顺序
                  • 实例对象自身的__dict__字典
                  • 对于类对象的__dict__字典
                  • 如果有父类,会往上层的__dict__字典中检测
                  • 如果没有找到,又定义了__getattr__方法,就会调用这个方法
                2. 而在上述的整个过程当中,是如何将描述器的__get__方法给嵌入到查找机制当中?
                3. 就是通过这个方式进行实现:
                  • _getattribute_
                  • 内部实现模拟:如果实现了描述器方法__get__,就会直接调用;如果没有则按照上面的机制去查找
          5. 注意:描述器和实例属性同名时,操作优先级

            • 资料描述器 :get、set

            • 非资料描述器:仅实现了get方法

            • 资料描述器 > 实例属性 > 非资料描述器

            • 装饰器:类实现如下:

              #一
              class Check:
                  def __init__(self,func):
                      self.f = func
                  def __call__(self, *args, **kwargs):
                      print("登陆验证")
                      self.f()
              
              def fashuoshuo():
                  print("发说说")
              fashuoshuo1 = Check(fashuoshuo)
              fashuoshuo1()
              #二
              class Check:
                  def __init__(self,func):
                      self.f = func
                  def __call__(self, *args, **kwargs):
                      print("登陆验证")
                      self.f()
              @Check
              def fashuoshuo():
                  print("发说说")
              fashuoshuo()
              

面向对象在python中的实现(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值