一、封装

把一堆东西装在一个容器里  函数和属性装到了一个非全局的命名空间
class A:
__N = 123 # 静态变量
def func(self):
print(A.__N) # 在类的内部使用正常
a=A()
a.func()
print(A.__N) # 在类的外部直接使用 报错
print(A._A__N)   # python就是把__名字当成私有的语法
定义一个私有的名字 : 就是在私有的名气前面加两条下划线 __N =123
所谓私有,就是不能在类的外面去引用它
一个私有的名字 在存储的过程中仍然会出现在A.__dict__中,所以我们仍然可以调用到。
python对其的名字进行了修改: _类名__名字
只不过在类的外部调用 :需要“_类名__名字”去使用
在类的内部可以正常的使用名字

_A__N
在类内 只要你的代码遇到__名字,就会被python解释器自动的转换成_类名__名字

私有的属性
class B:
def __init__(self,name):
self.__name = name
def func(self):
print('in func : %s'%self.__name)
b = B('alex')
print(b._B__name)
b.func()
私有的方法
class C:
def __wahaha(self):
print('wahaha')
def ADCa(self):
self.__wahaha()
c = C()
# c._C__wahaha()
c.ADCa() 在类中,静态属性,方法,对象属性都可以变成私有的,只需要在这些名字之前加上__

面试题
class D:
def __func(self): # '_D__func'
print('in func')
class E(D):
def __init__(self):
self.__func() # '_E__func'
e = E() # 会报错
私有的名字不能被子类继承
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

class F:
pass
F.__name = 'alex' # 不是在创建私有属性
print(F.__name)
print(F.__dict__)
变形只在类的内部发生 class F:
def ADCa(self):
self.__name = 'alex' # _F__name
f = F()
f.ADCa()
print(f._F__name)
java中的对比
public 公有的 在类的内部可以使用,子类可以使用,外部可以使用 python中所有正常的名字
protect 保护的 在类的内部可以使用,子类可以使用,外部不可以使用 python中没有
private 私有的 只能在类的内部使用,子类和外部都不可以使用 python中的__名字 私有的用法
当一个方法不想被子类继承的时候
有些属性或者方法不希望从外部被调用,只想提供给内部的方法使用

描述一个房子
单价
面积
长宽高
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('鹏鹏',100,2,1,0.5)
print(r.name)
print(r.price)
print(r.area()) # 查长宽高就报错

二、property

人体BMI指数
体质指数(BMI)=体重(kg)÷身高^2(m)
写一个类 描述人体BMI指数
class Person:
def __init__(self,name,gao,zhong):
self.name = name
self.__gao = gao
self.__zhong = zhong
   @property
def BMI(self):
return self.__zhong / self.__gao**2
a=Person('zx',170,80)
print(a.BMI)
将一个方法伪装成一个属性
并不会让你的代码有什么逻辑上的提高
只是从调用者的角度上换了一种方式,使之看起来更合理
@property 能够将一个方法伪装成一个属性
从原来的的对象名.方法名(),变成了对象名.方法名
只是让代码变的更美观

如果有重名的名字
class Person:
def __init__(self,name,weight,height):
self.name = name
self.__height = height
self.__weight = weight
@property
def bmi(self):
return self.__weight / self.__height ** 2
print(Person.__dict__)
p = Person('大表哥',92,1.85)
print(p.__dict__)
print(p.bmi) # 对这个属性 只能看了 被property装饰的bmi仍然是一个方法 存在Person.__dict__
对象的.__dict__中不会存储这个属性 在一个类加载的过程中,会先加载这个中的名字,包括被property装饰的
在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性,
如果有就不能再在自己对象的空间中创建这个属性了
 
from math import pi
class Circle:
def __init__(self,r):
self.r = r
@property
def area(self):
return pi*self.r**2 @property
def perimter(self):
return 2*pi*self.r
a=Circle(10)
print(a.area)
print(a.perimter)
c.r = 15  #改变属性,给属性重新赋值
print(c.area)
print(c.perimeter

方法伪装成的属性的修改

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) alex
p.name = 'sb'
print(p.name) sb
p.name = 123 输入有误
方法伪装成的属性的删除

class Person:

    def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name
@name.deleter
def name(self):
del self.__name
p = Person('alex')
print(p.name)
del p.name #只是执行了被@name.deleter装饰的函数
print(p.name)
@property --> func     将方法伪装成属性,只观看的事儿
@func.setter --> func 对伪装的属性进行赋值的时候调用这个方法 一般情况下用来做修改
@func.deleter --> func 在执行del 对象.func的时候调用这个方法 一般情况下用来做删除 基本不用
商品的 折扣
有一个商品 : 原价 折扣
当我要查看价格的时候 我想看折后价
class Goods:
def __init__(self,name,orinig_price,discount):
self.name = name
self.__orinig_price = orinig_price
self.__discount = discount
@property
def price(self):
return self.__orinig_price * self.__discount
@price.setter
def price(self,new_price):
self.__orinig_price = new_price
a = Goods('橙子',10,0.8)
print(a.price)
a.price = 20
print(a.price)
property的两个作用:
将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性
将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性

三、classmethod与staricmethod

不借助对象改变静态变量
class Goods:
__discount = 0.8
def __init__(self, name, orinig_price, ):
self.name = name
self.__orinig_price = orinig_price
@property
def price(self):
return self.__orinig_price * Goods.__discount
@classmethod
def change_discount(cls,new_price): 类方法 可以直接被类调用 不需要默认传对象参数 只需要传一个类参数就可以了
cls.__discount = new_price
Goods.change_discount(1) 不依赖对象的方法 就应该定义成类方法 类方法可以任意的操作类中的静态变量
a = Goods('橙子',10)
print(a.price)

staticmethod
使用什么样的方法要看具体用到了哪些名称空间中的变量
  当一个方法要使用对象的属性时 就使用普通的方法
  当一个方法要使用类中的静态属性时 就使用类方法
  当一个方法既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法
class Student:
def __init__(selfn,name):pass
@staticmethod
def login(): login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可
user = input('user')
if user == 'alex'
print('ok')
else:
print('bad')
Student.login()
使用什么样的方法要看具体用到了哪些名称空间中的变量完全面向对象编程
先登录 后 实例化
还没有一个具体的对象的时候 就要执行login方法

0417 封装 property、classmethod、staricmethod的更多相关文章

  1. python 全栈开发,Day22(封装,property,classmethod,staticmethod)

    一.封装 封装 : 广义上的 :把一堆东西装在一个容器里 狭义上的 :会对一种现象起一个专门属于它的名字 函数和属性装到了一个非全局的命名空间 —— 封装 隐藏对象的属性和实现细节,仅对外提供公共访问 ...

  2. 初识面向对象(钻石继承,super,多态,封装,method,property,classmethod,staticmethod)

    组合 什么有什么的关系 一个类的对象作为另一个类的对象继承 子类可以使用父类中的名字(静态属性 方法)抽象类和接口类 只能不继承,不能被实例化 子类必须实现父类中的同名方法———规范代码 metacl ...

  3. python 类的封装/property类型/和对象的绑定与非绑定方法

    目录 类的封装 类的property特性 类与对象的绑定方法与非绑定方法 类的封装 封装: 就是打包,封起来,装起来,把你丢进袋子里,然后用绳子把袋子绑紧,你还能拿到袋子里的那个人吗? 1.隐藏属性和 ...

  4. Python10/24--组合/封装/property装饰器/多态

    组合的应用: 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 3. 如何用组合 '''class Foo: aaa=111 ...

  5. 封装||property

    封装 封装:主要是指在类的定义阶段将,以__开头的属性名进行变形..例如:__name ==> _People__name 封装的主要特点: 1.在类外部无法直接__name,想要在外部调用可以 ...

  6. python基础学习 Day19 面向对象的三大特性之多态、封装 property的用法(1)

    一.课前内容回顾 继承作用:提高代码的重用性(要继承父类的子类都实现相同的方法:抽象类.接口) 继承解释:当你开始编写两个类的时候,出现了重复的代码,通过继承来简化代码,把重复的代码放在父类中. 单继 ...

  7. 10 python 封装----@property的用法

    1.基本概念 在python中用双下划线开头的方式将属性隐藏起来(设置成私有的) #其实这仅仅这是一种变形操作 #类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式: class A ...

  8. 面向对象 - 封装/property - 总结

    面向对象 - 封装: 封装:在类定义阶段,以__开头的属性名发生了变形 eg: __x --> _A__x / __foo --> _A__foo 1.特点: 1.在类外部无法直接访问 _ ...

  9. @property, @classmethod基本用法

    @property 废话少说,贴上代码(代码参考@廖雪峰教程) class Student(object): def __init__(self, score): self._score = scor ...

随机推荐

  1. Google 商店

    Google 商店地址:https://store.google.com/

  2. Android6.0系统添加那些新特性

        北京时间9月30日凌晨在美国旧金山举行2015年秋季新品公布会.在公布会上代号为"Marshmallow(棉花糖)"的安卓6.0系统正式推出.新系统的总体设计风格依旧保持扁 ...

  3. 在ubuntu1604上使用aria2下载coco数据集效率非常高

    简单的下载方法: 所以这里介绍一种能照顾大多数不能上外网的同学的一种简单便捷,又不会中断的下载方法:系统环境: Ubuntu 14.04 方法: a. 使用aria2 搭配命令行下载.需要先安装: s ...

  4. spark+kafka 小案例

    (1)下载kafka的jar包 http://kafka.apache.org/downloads spark2.1 支持kafka0.8.2.1以上的jar,我是spark2.0.2,下载的kafk ...

  5. MySQL_常用SQL语句

    1.按小时统计的语句 select concat(date_format(gmt_create, "%Y-%m-%d %k:00~"), hour(gmt_create)+1, & ...

  6. oracle复合索引的选择和使用

    声明:虽然题目是Oracle.但同样适合MySQL InnoDB索引          在大多数情况下.复合索引比单字段索引好     很多系统就是靠新建一些合适的复合索引.使效率大幅度提高      ...

  7. who 查看系统登录用户

    who  查看所有登录用户 whoami   查看自己的登陆名 w users last

  8. [WebGL入门]二十五,点光源的光照

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明.我会加上[lufy:].另外,鄙人webgl研究还不够深入,一些专业词语.假设翻译有误,欢迎大家指 ...

  9. PathInfo模式的支持

    pathinfo,一种伪静态的用法, 1.让 Apache 支持 PathInfo 配置的 Apache 版本 : 2.2.13 在配置文件中加入 <Files *.php> Accept ...

  10. 下载yum安装的rpm包

    方法一 通过yum自带的yumdownloader工具进行下载,这个工具是由yum-utils这个软件安装生成的 执行如下命令,检查yum-utils是否存在: rpm -qa |grep yum-u ...