zoukankan      html  css  js  c++  java
  • python 面向对象专题(五):私有成员、类方法、静态方法、属性、isinstance/issubclass

    https://www.cnblogs.com/liubing8/p/11325421.html

    1. 私有成员

    1. 私有类的属性:在内部可以访问(本类内部方法中),类的外部不能访问

      代码示例:

      # 在内部可以访问(本类内部方法中)
      class A:
          name = '张三'
          __name = '李四'  # 私有类的属性
          def func(self):
              print(self.name)
              print(self.__name)
      obj = A()
      obj.func()
      
      # 类的外部不能访问
      class A:
          name = '张三'
          __name = '李四'  # 私有类的属性
          def func(self):
              pass
      obj = A()
      print(obj.name)
      print(A.__name)   # 报错
      print(obj.__name)  # 报错
    2. 私有对象属性:只能在类的内部使用,不能在外部及派生类中使用

      代码示例:

      class A:
          name = '张三'
          __name = '李四'
      
      class B(A):
          def func(self):
              print(self.__name)
      
      obj = B()
      print(obj.__name)   # 不可以
      obj.func()   # 不可以
    3. 私有类的方法:只能在类的内部使用,不能在外部及派生类中使用

      代码示例:

      class A:
      
          def func(self):
              self.__func()
              print('in A func')
      
          def __func(self):
              print('in A __func')
      
      obj = A()
      obj.func()   # 可以
      obj.__func()   # 不可以
    4. 对于私有类成员来说:当你遇到重要的数据/功能,(只允许本类使用的一些方法,数据)设置成私有成员
    5. Python中所有私有成员都是纸老虎,形同虚设,类在加载时,只要遇到类中的私有成员,都会在私有成员前面加上_类名

      代码示例:

      class A:
      
          name = '张三'
          __name = '李四'  # 私有类的属性
      
          def __func(self):
              print('in __func')
      
      print(A.__dict__)
      print(A._A__name)

    2. 类方法

    方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

    • 类方法:一般就是通过类名去调用的方法,并且自动将类名地址传给cls,如果通过对象调用也可以,但是传的地址还是类名地址,并不是所有实例化都是在类外面

    • 类方法的作用:得到类名可以实例化对象,可以操作类的属性

    • 定义:使用装饰器@classmethod.第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法)

    • 代码示例:

      class A:
          def func(self):
              print('实例方法')
          @classmethod
          def cls_func(cls):
              print(f'cls---->{cls}')
              print('类方法')
      print(A)
      A.cls_func()
      obj = A()
      obj.cls_func()
    • 应用示例:创建学生类,只要实例化一个对象,写一个类方法,统计一下具体实例化多少个学生?

      class Student:
          count = 0
          def __init__(self,name,id):
              self.name = name
              self.id = id
              Student.addnum()
          @classmethod
          def addnum(cls):
              cls.count = cls.count + 1
          @classmethod
          def getnum(cls):
              return cls.count
      
      obj1 = Student('张三', 12343243243)
      obj2 = Student('李四', 12343243243)
      obj3 = Student('王五', 12343243243)
      
      print(Student.getnum())

    3. 静态方法

    • 静态方法:不依赖对象与类的,其实静态方法就是函数

    • 作用:保证代码的规范化,合理的划分,后续维护性高

    • 定义:使用装饰器@staticmethod.参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法

    • 代码示例:

      import time
      class TimeTest(object):
          def __init__(self, hour, minute, second):
              self.hour = hour
              self.minute = minute
              self.second = second
          @staticmethod   # 相当于函数的作用
          def showTime():
              return time.strftime("%H:%M:%S", time.localtime())
      print(TimeTest.showTime())
      t = TimeTest(2, 10, 10)
      nowTime = t.showTime()
      print(nowTime)

    4. 属性

    • 属性:property将执行一个函数需要函数名(),换成直接函数名
      将动态方法伪装成一个属性,虽然在代码级别上没有什么提升,但是让你看起来更合理

    • 代码示例:

      class Bmi:
          def __init__(self,name,height,weight):
              self.name = name
              self.height = height
              self.weight = weight
          def bmi(self):
              return self.weight/self.height**2
      obj = Bmi(张三', 1.83, 65)
      print(obj.bmi())
      
                
      # 结果虽然实现了,但是逻辑上感觉不合理.bmi应该是类似于name,age,height等名词,但是把它当做方法使用了.
      class Bmi:
          def __init__(self,name,height,weight):
              self.name = name
              self.height = height
              self.weight = weight
          @property
          def bmi(self):
              return self.weight/self.height**2
      obj = Bmi('张三', 1.83, 65)
      print(obj.bmi)
                
      # property 将执行一个函数需要函数名()变换成直接函数名.
      # 将动态方法 伪装 成了一个属性,虽然在代码级别上没有什么提升,但是让你看起来更合理.
    • property 是一个组合

      class Foo:
          @property
          def bmi(self):
              print('get的时候运行我啊')
          @bmi.setter
          def bmi(self,value):
              print(value)
              print('set的时候运行我啊')
              # return 111  # 无法得到返回值
          @bmi.deleter
          def bmi(self):
              print('delete的时候运行我啊')
              # return 111  # 无法得到返回值
      obj = Foo()
      obj.bmi 
      obj.bmi = 666 # 操作命令 这个命令并不是改变bmi的值,而是执行被bmi.setter装饰器装饰的函数
      obj.bmi(666)  # 报错
      del obj.bmi
      
      # 结果:
      get的时候运行我啊
      666
      set的时候运行我啊
      delete的时候运行我啊

      设置属性的两种方式:

      # 1. 利用装饰器设置属性.
      class Foo:
          @property
          def bmi(self):
              print('get的时候运行我啊')
      
          @bmi.setter
          def bmi(self,value):
              print(value)
              print('set的时候运行我啊')
              # return 111  # 无法得到返回值
      
          @bmi.deleter
          def bmi(self):
              print('delete的时候运行我啊')
              # return 111  # 无法得到返回值
      
      2. 利用实例化对象的方式设置属性.
      class Foo:
          def get_AAA(self):
              print('get的时候运行我啊')
          def set_AAA(self,value):
              print('set的时候运行我啊')
          def delete_AAA(self):
              print('delete的时候运行我啊')
          AAA = property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应
      f1=Foo()
      f1.AAA
      f1.AAA='aaa'
      del f1.AAA

    5. 内置函数 isinstance issubclass

    • isinstance 判断的是对象与类的关系

      class A:
          pass
      class B(A):
          pass
      obj = B()
      
      # isinstance(a,b) 判断的是 a是否是b类 或者 b类派生类 实例化的对象.
      print(isinstance(obj, B))  # True
      print(isinstance(obj, A))  # True
    • issubclass 判断的是类与类之间的关系

      class A:
          pass
      class B(A):
          pass
      class C(B):
          pass
      
      # issubclass(a,b) 判断的是 a类是否是b类的派生类 或者 b类派生类 的派生类.
      # issubclass(a,b) 判断的是 a类是否是b类 子孙类.
      print(issubclass(B,A))
      print(issubclass(C,A))

    6. 总结:

    1. 对象如果改变了类的静态属性, 具体他进行了什么操作?
      将类中的静态属性变成可变的数据类型.
      对象调用类的方法,方法中对类的属性进行改变.

    2. 对象不能修改类的属性,示例代码如下:

      class A:
          a = 1
          b = 2
          def __init__(self):
              c = 3
      obj1 = A()
      obj2 = A()
      obj1.a = 3
      obj2.b = obj2.b + 3
      
      print(A.a)  #1
      print(obj1.b)  #2
      print(obj2.b)  #5
      print(obj2.c)   #报错
  • 相关阅读:
    1025WHERE执行顺序以及MySQL查询优化器
    1025基础REDIS
    1025关于explain的补充1
    1021mysql 全外连接
    python开发进程:进程开启方式&多进程
    python开发面向对象进阶:反射&内置函数
    python开发socket套接字:粘包问题&udp套接字&socketserver
    python开发面向对象基础:封装
    python开发模块基础:异常处理&hashlib&logging&configparser
    python开发面向对象基础:接口类&抽象类&多态&钻石继承
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12862238.html
Copyright © 2011-2022 走看看