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) """ 李业 无法找到 无法找到 """
在类的派生类不能访问
class A: name = "李业" __name = "钢哥" class B(A): def func(self): print(self.__name) obj = B() print(obj.__name) obj.func()
私有对象属性
只能在类的内部使用,不能在类外部以及派生类使用
class A: def __init__(self, name, pwd): self.name = name self.__pwd = pwd def md5(self): self.__pwd = self.__pwd + "123" obj = A("李业", "liyedsb") print(obj.__pwd) """ 无法找到 """
私有类的方法
class A: def func(self): self.__func() print("in A func") def __func(self): print("in A __func") obj = A() obj.func() """ in A __func in A func """ obj.__func() """ 无法找到 """
对于私有成员来说: 当你遇到重要的数据,功能,(只允许本类使用的一些方法,数据)设置成私有成员
特殊方法(默认不使用)
class A: name = "李业" __name = "钢哥" def __func(self): print("in __func") print(A.__dict__) """ {'__module__': '__main__', 'name': '李业', '_A__name': '钢哥', '_A__func': <function A.__func at 0x000002F6FFB79A60>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None} """ print(A._A__name) """ 钢哥 """ # 类从加载时, 只要遇到类中的私有成员, 都会在私有成员前面加上 _类名
2.类的其他方法
类方法
class A: def func(self): print("实例方法") @classmethod def cls_func(cls): print(f"cls---->{cls}") obj = cls() print(obj) print("类方法") print(A) A.cls_func() """ <class '__main__.A'> cls----><class '__main__.A'> <__main__.A object at 0x000001C3B5F874E0> 类方法 """ obj = A() obj.cls_func """ 输出为空,因为cls_func是一个类方法,传入cls的是类的内存地址,所以对象无法调用 """ # 类方法,一般就是通过类名去调用的方法,并且自动将类名地址传给cls,但是如果通过对象调用也可以,但是传的还是类名地址 A.cls_func() """ cls----><class '__main__.A'> <__main__.A object at 0x00000234B9C17630> 类方法 """
类方法有什么用
1.得到类名可以实例化对象
2.可以操作类的属性
简单引用
创建学生类,只要实例化一个对象,写一个类方法,统计一下具体实例化多少个学生
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('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) obj1 = Student('liye', 12343243243) print(Student.getnum())
静态方法
class A: def func(self): print("实例方法") @classmethod def cls_func(cls): pass @staticmethod def static_func(): print("静态方法") A.static_func() """ 静态方法 """ # 静态方法是不依赖于对象与类的,其实静态方法就是函数,保证代码的规范性,合理的划分,后续维护性高,但是调用依然用类名调用 # 实例 import time class TimeTest(object): area = "中国" def __init__(self, hour, minute, second): self.hour = hour self.minute = minute self.second = second def change_time(self): print(f"你想调整的时间:{self.hour}时{self.minute}分{self.second}秒") @staticmethod def showTime(): return time.strftime("%H:%M:%S",time.localtime()) t = TimeTest(2, 10, 10) t.change_time() print(TimeTest.showTime()) # showTime函数,与类和对象没有任何关系,但是都是与时间有关,所以为了规范合理,放在一起,调用时用类名调用
3.属性
示例:
BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24-27 肥胖:28-32 非常肥胖, 高于32 体质指数(BMI)=体重(kg)÷身高^2(m) EX:70kg÷(1.75×1.75)=22.86 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) # 结果虽然实现了,但是逻辑上感觉不合理,bmi应该是类似于name,age,height,等名词,但是把它当做方法使用了
property
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 将执行一个函数需要函数名()变换成直接函数名,将动态方法 伪装 成了一个属性,虽然在代码级别上没有什么提升,但是让你看起来更合理
组合
class Foo: @property def bmi(self): print("get的时候运行我") @bmi.setter def bmi(self, value): print(value) print("set的时候运行我") @bmi.deleter def bmi(self): print("delete的时候运行我") obj = Foo() obj.bmi obj.bmi = 666 del obj.bmi """ get的时候运行我 666 set的时候运行我 delete的时候运行我 """ # 应用场景: # 1.面试会考一些基本的调用,流程 # 2.工作中如果遇到了一些类似于属性的方法名,可以让其伪装成属性
设置属性的两种方式
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
4.isinstance和issubclass
isinstance
判断的对象与类的关系
class A: pass class B(A): pass obj = B() print(isinstance(obj,B)) print(isinstance(obj,A)) """ True True """ # isinstance(a,b) # 判断的是 a 是否是 b类 或者 b类派生类实例化的对象
issubclass
判断的是类与类的关系
class A: pass class B(A): pass class C(B): pass print(issubclass(B,A)) print(issubclass(C,A)) """ True True """ # issubclass(a,b) # 判断的是 a类 是否是 b类 或者 b类派生类的 派生类 # 判断的是 a类 是否是 b类的子孙类