封装:将类的属性隐藏

#先看如何隐藏

1,在定义的属性之前加入__.

class Foo:
__N=111111 #_Foo__N
def __init__(self,name):
self.__Name=name #self._Foo__Name=name def __f1(self): #_Foo__f1
print('f1')
def f2(self):
self.__f1() #self._Foo__f1() #在类内部调用的话可以
f=Foo('egon')
#这种隐藏需要注意的问题: 
#1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
# print(Foo.__dict__)
# print(f.__dict__)
# print(f._Foo__Name)
# print(f._Foo__N)

第二个问题:这种语法上的变形是在什么时候发生的

#在定义类阶段发生,并且只在这个阶段发生

比如说在上面的基础上,再定义一个Foo.__x=12121212121212121212

再去访问Foo.__x这个属性,

是可以访问的到的,不会被隐藏

第三个问题:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

#封装不是单纯意义上的隐藏

1,封装数据属性(内部能用,外部不能用,开一个接口给其他人使用,保证代码安全性)

  

  将属性隐藏起来,然后提供对外访问属性的接口,关键是我们在接口内定制一些控制逻辑从而严格控制对数据属性的使用

 class People:
def __init__(self,name,age):
if not isinstance(name,str):
raise TypeError('%s must be str' %name)
if not isinstance(age,int):
raise TypeError('%s must be int' %age)
self.__Name=name
self.__Age=age
def tell_info(self):
print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age)) def set_info(self,x,y):
if not isinstance(x,str):
raise TypeError('%s must be str' %x)
if not isinstance(y,int):
raise TypeError('%s must be int' %y)
self.__Name=x
self.__Age=y #p=People('egon',18)
#p.tell_info() # p.set_info('Egon','19')
#p.set_info('Egon',19)
#p.tell_info()

2,封装函数属性

  目标隔离复杂度。

  例如ATM内部有很多负复杂的函数,内部定义,但是对于用户来说,只需要记住取款,存款这几个功能就可以了。

 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()

静态属性property:

在类里面加入这个参数以后,调用函数不用加括号了。(加括号会报错)

相当于把功能伪装成一个数据,eg:

 class Foo:
@property #这里相当于把函数直接伪装了
def f1(self):
print('f1') f=Foo() # f.f1() f.f1

写一个例子:

'''
例: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 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) # p=People('egon',75,1.80)
# p.height=1.86
# print(p.bmi())  #这里是在没有加property这个属性的时候用的
# print(p.bmi) #在这里就可以直接输出值了

怎么功能添加访问,设置,删除的属性。

是在函数已经设置了静态属性的前提下,在设置函数.setter,函数.deleter等属性

 class Foo:
def __init__(self,x):
self.__Name=x @property
def name(self):
return self.__Name @name.setter
def name(self,val):
if not isinstance(val,str):
raise TypeError
self.__Name=val @name.deleter
def name(self):
# print('=-====>')
# del self.__Name
raise PermissionError # f=Foo('egon')
# print(f.name)
#
# # f.name='Egon'
# f.name=123123123213
# print(f.name)
#
# del f.name
# print(f.name)

  

Day8 封装 静态属性property的更多相关文章

  1. 静态属性property

    静态属性property(是通过对象去使用) property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 1 . 通过@property修饰过的函数属性,调用的时候无需在加() cla ...

  2. 静态属性property的本质和应用

    一.本质 静态属性property本质就是实现了get,set,delete三种方法 class Foo: @property def AAA(self): print('get的时候运行我啊') @ ...

  3. python静态属性@property、类方法@classmethod、静态方法@staticmethod和普通方法

    静态属性:即将类的函数通过@property属性封装,封装后实例调用该函数时,不再需要在函数后面加(),而是用类似调用数据属性的方式直接调用函数名称即可执行函数. 静态属性既可以访问类的属性,也可以访 ...

  4. 静态属性@property

    property 作用其实把类里面的逻辑给隐藏起来(封装逻辑,让用户调用的时候感知不到你的逻辑) property实例1:class Room: def __init__(self): pass @p ...

  5. Python学习第十六课——静态属性(property, classmethod, staticmethod)

    计算所居住房子的面积 普通写法 class Room: def __init__(self,name,owner,width,length,heigh): self.name=name self.ow ...

  6. day26 python学习 对象的接口,封装,私用属性 property

    # 抽象类和接口类 #** #不崇尚接口类 #python本身支持多继承,没有接口专用的语法.但是我知道接口的概念 # 接口类:# 是规范子类的一个模板,只要接口类中定义的,就应该在子类中实现# 接口 ...

  7. Day 19:面向对象【类方法】静态属性/静态属性/类方法

    静态属性  @property  class Mom: gender = "woman" def __init__(self,name,weight): self.name = n ...

  8. day16-封装(私有静态属性、私有属性、私有方法、类方法、静态方法)

    # 一: class P: __age = 30 #私有静态属性 def __init__(self,name): self.__name = name #私有属性:属性名前面加上双下划线是私有属性. ...

  9. php函数、类和对象以及类的封装、继承、类的静态方法、静态属性

    1.函数     php内置函数可以直接使用,如果没有安装php扩展即可     自定义函数 //函数function 函数名 function dump($var = null){ //支出默认参数 ...

随机推荐

  1. 讲究门面的Request

    为什么说Request讲究门面?注意这里所说的门面并非我们常理解的外表的意思,其实是说它使用了门面设计模式,门面的使用主要用于数据安全的考虑.一个大的系统体系的多个子系统之间涉及交互通信.一个系统中的 ...

  2. Request中Attribute 和 Parameter 的区别

    Attribute 和 Parameter 的区别 (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为 ...

  3. ROS_Kinetic_08 ROS的集成开发环境(IDEs)之使用Eclipse

    ROS_Kinetic_08 ROS的集成开发环境(IDEs)之使用Eclipse ROS支持的IDEs比较丰富,这里以Eclipse为例介绍一下. 具体内容参考:http://wiki.ros.or ...

  4. C语言野指针

    本文转载自:http://blog.csdn.net/xwdok/article/details/576497 "野指针"不是NULL指针,是指向"垃圾"内存的 ...

  5. (NO.00002)iOS游戏精灵战争雏形(七)

    接上一篇博文,我们继续完成射击的功能. 还是在MainScene.m中,添加initBullets方法: -(void)initBullets{ CCSprite *bullet; for (int ...

  6. Spring BeanFactory getBean 源码剖析

    首先看一张时序图 最开始,一切都来自这里: public static void main(String[] args) { ApplicationContext context = new Clas ...

  7. 更新Cocos2D支持Xcode 7

    原文链接(有节选简写) Apple已经释放出Xcode7,给我们带来了Swift2和每个平台的最新版本支持.Cocos2D却还在等待更新去兼容Apple的改变.不幸的是,SpriteBuilder还未 ...

  8. Mysql数据库安装和配置

    http://blog.csdn.net/pipisorry/article/details/46773507 Mysql数据库安装和配置.mysql语法.特殊符号及正则表达式的使用.MySQL备份与 ...

  9. 【一天一道LeetCode】#31. Next Permutation

    一天一道LeetCode系列 (一)题目 Implement next permutation, which rearranges numbers into the lexicographically ...

  10. 【Qt编程】Qt学习笔记<二>

    1.      QApplication类和QWidget类都包含在QtGui模块中.所以我们可以只包含这个头文件即可. 2.      在c++中,用new分配了内存空间就需要用delete来释放空 ...