面向对象进阶-1
面向对象进阶-1:
变量和属性的联系:
变量:存储数据的容器 如name = ’gauohan‘
属性:绑定到类或者对象的变量,即有归属的变量 属于谁的变量,那么这个变量叫成谁的属性
类的成员:
1.字段( 属性):
静态字段:
类变量(类属性,类字段):在类体中 但是在各个方法外
调用:类名.变量名 实例对象.变量名
普通字段:
实例变量(实例属性,实例字段):在任意类方法内部以self.变量名的方式定义的变量
调用:对象.变量名
局部变量:在类的函数中,函数执行完则被销毁
2.方法:
绑定方法(实例方法):
定义时:至少有一个self参数,谁调用此方法self就是谁,self的值python自动传递
调用:对象.方法() 无需传self参数
静态方法: 当方法中不需要用到任何对象中封装的属性和类中的属性,方法时定义一个静态方法
用@staticmethod修饰
定义时:可以有任意个参数,python不会对其进行任何参数的传递
调用:类名.方法() 对象.方法()
价值:将全局中零散的函数统一写到类中方便可读
静态方法实例
#静态方法
#实现计算2数和,判断数是不是质数
class num:
@staticmethod
def add(a,b):
return a+b
@staticmethod
def look(n):
if n < 2:
return False
for i in range(2,int(n**2)+1):
if n%i==0:
return False
return True
print(num.add(1,2))
print(num.look(13))
类方法: 当方法中不需要用到对象封装的内容,而是用当前类 则定义一个类方法
用@classmethod修饰
定义时:至少有一个cls参数,此方法在哪个类中cls就是当前类名,cls的值python自动传递
调用:类名.方法() 对象.方法()
类方法实例
#类方法
#实现动物类(含有创建动物实例方法,统计动物实例个数方法)
class Animal:
total_animals = 0 #类属性
def __init__(self,name):
self.name = name
Animal.total_animals+=1 #调用类属性 类名.属性
@classmethod
def new_animal(cls,name): #创建动物类对象函数
return cls(name)
@classmethod
def count_animal(cls): #读取类对象总数函数
print(f'{cls.total_animals}')
dog = Animal.new_animal('coke') #调用类方法 类名.方法
cat = Animal.new_animal('coke1')
Animal.count_animal()
3.属性的扩展:在面向对象编程中,“属性的扩展”通常围绕如何更灵活、安全地操作对象的属性展开,核心是通过**装饰器(如 Python 中的 @property 、 @属性名.setter 、 @属性名.deleter )**来增强属性的功能,实现对属性访问、修改、删除的精细控制。
读 改 删 (一般作用的是私有属性) 三者必须绑定在同一个方法名上才能工作(三者缺一不可)
1.读取私有属性功能 基础的property
定义:在方法上加@property 将方法变成属性
使用情况:想要访问私有属性 加上property后此方法变成属性 则可以像普通属性一样直接访问此伪装的属性从而间接访问私有属性 此方法仅需有一个self参数,无需而外参数
#读取私有属性
class Foo:
def __init__(self,name):
self.__name = name #设置私有属性,对象不能直接访问
@property #将func方法伪装成属性其内部代码正常执行不受影响
def func(self):
return self.__name
obj = Foo('guohan')
#obj.__name 私有属性无法通过对象直接访问
print(obj.func)
区别方法和属性
方法:obj.func1()
属性:obj.func2
2.修改私有属性功能 由于proper将方法伪装成属性原来的方法名即称为属性名
定义:用@属性名(被property修饰的方法名).setter 装饰一个同名方法
使用情况:修改私有属性的值
这样就可以像改普通属性一样修改私有属于 对象.属性 = 值
#修改私有属性
class Foo:
def __init__(self,name):
self.__name = name #设置私有属性,对象不能直接访问
@property
def func(self):
return self.__name
@func.setter
def func(self,value):
self.__name = value #满足私有属性只能在内部的公有方法进行操作
obj = Foo('guohan')
obj.func = 'gh'
print(obj.func)
3.删除私有属性功能
定义:@属性名.deleter
使用情况:删除私有属性
#删除私有属性
class Foo:
def __init__(self,name,pwd):
self.name = name #设置私有属性,对象不能直接访问
self.__pwd = pwd
@property
def func(self):
return self.__pwd
@func.setter
def func(self,value):
self.__pwd = value
@func.deleter
def func(self):
del self.__pwd
obj = Foo('guohan','123')
obj.func = 888
print(obj.name) #>>>guohan
print(obj.func) #>>>888
print(obj.__dict__) #>>>{'name': 'guohan', '_Foo__pwd': 888}
del obj.func
print(obj.__dict__) #>>>{'name': 'guohan'}
核心总结:三者的关系是“1个核心+2个可选功能”
- 1个核心: @property (读功能)是基础,没有它,setter和deleter就“没地方绑”,根本用不了;
- 2个可选功能:setter(改)和deleter(删)是附加在property上的,你可以按需加——比如只需要“读和改”,就只加setter;只需要“读”,就只保留基础的property;
- 最终效果:对外,你操作的是 obj.func (像普通属性);对内,实际走的是property、setter、deleter里的逻辑,既简单又安全。
补充强制访问:
# 强制访问私有成员
class Foo:
def __init__(self,name):
self.__x = name
obj = Foo('alex')
print(obj._Foo__x) # 强制访问私有实例变量