标签:设计者 ret 类的设计 设计 rom ini 新功能 info att
一、封装如何隐藏属性
class A: __x=1 def __init__(self,name): self.__name=name # self._A__name=name def __foo(self): # def _A__foo(self): print(‘run foo‘) # print(A.__x) # 没有这个值了 a = A(‘egon‘) print(a.__dict__) # {‘_A__name‘: ‘egon‘}
这种变形特点:
1、外部无法直接访问到 obj.__AttrName
2、在类内部 obj.__AttrName
3、子类无法覆盖父类 __开头的属性(根本不是一个名字)
class Foo: def __func(self): # _Foo__func(self) print(‘from foo‘) class Bar(Foo): # _Bar__func(self): def __func(self): print(‘from bar‘)
总结:
1、隐藏只在函数定义的时候才会发生
2、加上__ 后 只能在自己或者自己类里找
class B: __x=1 def __init__(self,name): self.__name=name print(B._B__x) B.__y=2 print(B.__dict__) #1.常态 class A: def foo(self): print(‘A.foo‘) def bar(self): print(‘A.bar‘) self.foo() class B(A): def foo(self): print(‘B.foo‘) b=B() b.bar() # A.bar B.foo #2.隐藏用法:只调取自己类的,不调取其他类的 class A: def __foo(self): # _A__foo print(‘A.foo‘) def bar(self): print(‘A.bar‘) self.__foo() # self._A__foo() class B(A): def __foo(self): #_B__foo print(‘B.foo‘) b=B() b.bar() # A.bar A.foo
二、封装的意义
封装数据属性:明确区分内外,控制外部对隐藏的属性的应用
class People: def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print(‘Name:<%s>Age:<%s>‘%(self.__name,self.__age)) def set_info(self,name,age): if not isinstance(name,str): print(‘名字必须是字符串‘) return if not isinstance(age,int): print(‘年龄必须是数字类型‘) return self.__name=name self.__age=age p=People(‘egon‘,18) # p.tell_info() # p.set_info(‘EGON‘,18) # 修改为这两个值 # p.tell_info() # 间接调取 p.set_info(123,18) p.tell_info()
封装数据属性:隔离复杂度
取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
隔离了复杂度,同时也提升了安全性
class ATM: def __card(self): print(‘插卡‘) def __auth(self): print(‘用户认证‘) def __input(self): print(‘输入取款金额‘) def __print_bill(self): print(‘打印账单‘) def __take_money(self): print(‘取款‘) def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() a=ATM() a.withdraw()
class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height**2) p1=People(‘egon‘,52,1.67) print(p1.bmi)
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
@property 封装逻辑,像是在调取一个普通属性,隐藏了内部逻辑,外观看着像是调取普通的属性。
封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;
而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。
这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。
#类的设计者 class Room: def __init__(self,name,owner,width,length,high): self.name=name self.owner=owner self.__width=width self.__length=length self.__high=high def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积 return self.__width * self.__length #使用者 >>> r1=Room(‘卧室‘,‘egon‘,20,20,20) >>> r1.tell_area() #使用者调用接口tell_area 400 #类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码 class Room: def __init__(self,name,owner,width,length,high): self.name=name self.owner=owner self.__width=width self.__length=length self.__high=high def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了 return self.__width * self.__length * self.__high #对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能 >>> r1.tell_area() 8000
标签:设计者 ret 类的设计 设计 rom ini 新功能 info att
原文地址:https://www.cnblogs.com/hexiaorui123/p/10201456.html