作者:龙娃爸爸3 | 来源:互联网 | 2023-09-25 19:45
1,封装把函数和属性装到了一个非全局的命名空间就是封装。怎么封装呢?首先定义一个私有的名字:就是在私有的名字前加双下划线,所谓私有的,就是在类的外面不能引用。一个私有的名字在存储的
1,封装
把函数和属性装到了一个非全局的命名空间就是封装。
怎么封装呢?
首先定义一个私有的名字:
class Person:
__n = ‘person‘#定义个私有变量
def func(self):
pass
就是在私有的名字前加双下划线,所谓私有的,就是在类的外面不能引用。一个私有的名字在存储的过程中仍然出现在类的dict中,所以我们仍然可以调用到。只不过在pyhton 对其名字进行了修改_类名__名字。
只不过在外部调用,需要“_类名__名字”使用,在类的内部可以正常的使用名字。在类内,只有你的代码遇到__名字,就会被python解释权自动的转换成 _类名__名字 。
在类中,静态属性和方法,对象的属性都可以变成私有的,只需要在这些名字之前加 __(双下划线)名字。
私有的名字不能被子类继承。
class D:
def __init__(self):
self.__func()
def __func(self):
print(‘in D‘)
class E(D):
def __func(self):
print(‘in E‘)
e = E() # in D
以上为例,私有名字,在类内使用的时候,就是会变形成_类__方法名,以此为例,没有双下划线会先找E中的func,但是有了双下划线,会在调用这个名字的类D中直接找到_D__func。
2,和java之间的对比
public 公有的类 ,在类的内部可以使用,子类可以使用,外部可以使用。python中所有正常的名字都是公有的。
protect 保护的类 ,python中没有。
private 私有的类,只能在类的内部使用,子类和外部都不可以使用,python中就是私有 的名字 __名字
3,私有的语法
1, 当一个方法不想被子类继承的时候。
2,有些属性或者方法不希望从外部被调用,只想提供给内部的方法使用。
class Room:
def __init__(self,name,price,length,width,height):
self.name = name
self.price = price
self.__length = length
self.__width = width
self.__height = height
def area(self):
return self.__length * self.__width
r = Room(‘yuyu‘,10000,10,20,12)
print(r.area())
print(r.price)
print(r.name)
View Code
4,property方法
写一个类描述人的BMI指数,体质指数(BMI) = 体重(kg)/ 身高**2(米)
class Person:
def __init__(self,name,weight,height):
self.name = name
self.__height = height
self.__weight = weight
def cal_BMI(self):
return self.__weight / self.__height ** 2
@property
def bmi(self):
return self.__weight / self.__height ** 2
p = Person(‘bge‘,60,1.68)
print(p.bmi)
property就是将一个方法伪装成一个属性,并不会让你的代码有什么逻辑上的提高,只是从调用者的角度上换了一个方式,使之看起来合理。方法中一般涉及的都是计算过程。
调用方法变成了从原来的 对象名.方法名() ,变成了 对象名.方法名。只是让代码变得更美观。
5,方法伪装成方法的修改 setter
所要修改的函数名必须一致
class Person:
def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter#
def name(self,new_name):
if type(new_name)is str:
self.__name = new_name
else:
print(‘您提供的姓名数据类型不合法‘)
p = Person(‘alex‘)
print(p.name)
p.name = ‘alex_sb‘
print(p.name)
p.name = 123
print(p.name)
View Code
6,方法伪装成属性的删除 deleter
class Person:
def __init__(self,n):
self.__name = n
@property
def name(self):
return self.__name
@name.deleter
def name(self):
print(‘name 被删除了‘)
@name.deleter
def name(self):
del self.__name
p = Person(‘alex‘)
print(p.name)
del p.name
print(p.name)
View Code
小结:@property ---->func 将方法伪装成属性,只管看的事。
@func.setter---->func 对伪装的属性进行赋值的时候 调用这个方法,一般情况下用来修改。
@func.deleter---->func 在执行del 对象.func的时候调用这个方法,一般情况下用来删除,一般不用。
7,classmethod
class Goods:
__discount = 0.8
def __init__(self,name,origin_price):
self.name = name
self.__price = origin_price
@property
def price(self):
return self.__price * Goods.__discount
@classmethod
def change_discount(cls,new_discount): # 类方法 可以直接被类调用 不需要默认传对象参数 只需要传一个类参数就可以了
cls.__discount = new_discount
Goods.change_discount(1) # 不依赖对象的方法 就应该定义成类方法 类方法可以任意的操作类中的静态变量
apple = Goods(‘apple‘,5)
banana = Goods(‘banana‘,8)
print(apple.price)
print(banana.price)
View Code
8,staticmethod
当一个方法既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmehtod
class Student:
def __init__(self,name):pass
@staticmethod
def login(a): # login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可
user = input(‘user :‘)
if user == ‘alex‘:
print(‘success‘)
else:
print(‘faild‘)
Student.login(1)
View Code
4-17日 封装和几个内置方法