python 面向对象专题(五):基础(五)私有成员、类方法、静态方法、属性、isinstance/issubclass
https://www.cnblogs.com/liubing8/p/11325421.html
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 func(self): self.__func() print('in A func') def __func(self): print('in A __func') obj = A() obj.func() # 可以 obj.__func() # 不可以
-
对于私有类成员来说:当你遇到重要的数据/功能,(只允许本类使用的一些方法,数据)设置成私有成员
-
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. 总结:
-
对象如果改变了类的静态属性, 具体他进行了什么操作?
将类中的静态属性变成可变的数据类型.
对象调用类的方法,方法中对类的属性进行改变. -
对象不能修改类的属性,示例代码如下:
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) #报错
本文来自博客园,作者:秋华,转载请注明原文链接:https://www.cnblogs.com/qiu-hua/p/12862238.html