python 类的封装/property类型/和对象的绑定与非绑定方法
类的封装
封装: 就是打包,封起来,装起来,把你丢进袋子里,然后用绳子把袋子绑紧,你还能拿到袋子里的那个人吗?
1.隐藏属性和方法,外部(类的外部)无法使用,内部(类额内部)可以使用,在类定义阶段就执行了,真的想引用,就使用_类名__属性名
封装分为两个层面:
第一个层面: 对象能拿到类的东西,但是类能拿到对象的东西吗?
class Foo():
count = 0
print(count)
f = Foo()
print(f.count)
f.name = 'nick' # 对 对象进行了封装,类拿不到对象的name
print(Foo.name) # AttributeError: type object 'Foo' has no attribute 'name'
AttributeError 英文:属性错误的意思
第二个层面的: 内部(类的内部)可以使用,外部(类的外部)不可以使用,在你需要封装的属性前面加上__
# 以前定义变量并不会以下划线开头,以下划线开头的变量,比如隐藏属性,或者以下划线开头方法,在某种情况下会自动调用,比如__init__()
lass People():
lover = 'male'
print('in',lover) # 内部可用lover
print('out',People.lover) # 外部可用lover
# 属性隐藏,在属性前加__
class People():
__lover = 'male'
print('in',__lover) # 内部可用__lover
# print('out',People.__lover) # 外部不可以用__lover
print('out',People._People__lover) # out male 如果你真的要拿,_类名__属性去拿(不可能这样做)
# 函数隐藏,在函数前加__函数名
# 正常
class People():
def eat(self):
print('eat')
People.eat(111) # 类调用,需要传参
pe = People()
pe.eat()
# 隐藏方法
class People():
__love_people = 'male'
# print('in',love_people) 报错
# print('in',__love_people) 报错
# 定义一个吃饭的流程:拿碗,拿筷子,吃饭
def __nawan(self):
print('nawan')
def __nakuaizi(self):
print('nakuaizi')
def __chifan(self):
print('chifan')
def chifan_all(self): # 吃饭
self.__nawan()
self.__nakuaizi()
self.__chifan()
# print('out',People.__nawan(11)) # 报错,不可以引用内部的__nawan函数,函数进行了隐藏
p = People()
# print('out',p.nawan())
# print('out',p.nakuaizi())
# print('out',p.chifan())
print('out',p.chifan_all())
2.隐藏模块内的函数/变量 _x: from module import * (无法导入),from module import _x(不合理)
# 正常情况下
# m1.py
x= 10
def f1():
print('from f1')
# m2.py
from m1 import x
# from m1 import *
print(x)
f1()
#现在对模块内的函数/变量 进行隐藏
# m1.py
_x= 10
def __f1():
print('from f1')
# m2.py
from m1 import _X,__f1 (可以导入_x,__f1,但是不合理,变量/函数前面加_或者__都行,主要原模块m1中变量或者函数名写成什么样,m2单独导入就导什么样)
# from m1 import * (导不出_x,__f1) ,除掉注释,下面两行代码都会报错
print(_x) # 可以导入
__f1() # 可以导入
对属性这个封装有什么用:藏起来了,保护了你的隐私,类内部的属性不想让其他人访问
对方法封装有什么好处:精简了代码,你吃饭就使用chifan_all这个方法就可以了,不需要去关心其他的操作,并且外部调用者也不知道你内部发生了什么
做一个小练习,理解封装其实在定义阶段就已经执行了,会把私有属性__f1变成 _Foo__f1,之后都不会做这种处理
class Foo:
def __f1(self):
print('Foo.f1')
def f2(self):
print('_Foo__f1')
self.__f1()
print(Foo.__dict__) #注意字典中 __f1 变成了什么,_Foo__f1 {'__module__': '__main__', '_Foo__f1': <function Foo.__f1 at 0x00000231DCBE0488>, 'f2': <function Foo.f2 at 0x00000231DCBE0510>, '__dict__': <attr
class Bar(Foo):
def __f1(self):
print('Bar.f1')
bar = Bar() # 实例化一个对象
bar.f2() # 对象bar中找f2,没有,然后Bar类也没有,去父类Foo找,找到f2,打印 _Foo__f1,再执行self.__f1(),self是对象,对象有__f1,打印 Bar.f1
bar.f2() # _Foo__f1,Bar.f1
class Foo():
__count = 0
foo = Foo()
print(foo)
foo.__y = 1 # 给对象foo添加属性__y
print(foo.__y) # 1
类的property特性
@property : 被@property 装饰的函数会从函数变成属性,也就是说直接 .函数名,不需要加括号使用
# BMI
class People():
def __init__(self,height,weight):
self.height = height
self.weight = weight
@property
def bmi(self):
return self.weight/(self.height**2)
peo = People(1.8,70)
print(peo.height)
# print(peo.bmi()) 没用 @property的时候需要这样写
print(peo.bmi)
@方法名.setter : 被@方法名.setter 装饰的函数,方法名修改,会执行这个装饰的函数
@方法名.deleter: 被@方法名.deleter 装饰的函数,方法名删除,会执行这个装饰的函数
# 装饰器用法(只在Python3中使用)
class People():
def __init__(self,height,weight):
self.height = height
self.weight = weight
@property # 获取值的时候触发,你不需要加括号使用,不能加参数
def bmi(self):
return self.weight/(self.height**2)
@bmi.setter # 在修改bmi的时候触发,必须得加参数
def bmi(self, value):
print(f'你已经成功修改为{value}')
@bmi.deleter # 在删除bmi的时候触发,不能加参数
def bmi(self):
print('delter')
peo = People(1.8,70)
print(peo.bmi)
print('*'*50)
peo.bmi = 50
print('*'*50)
del peo.bmi
类与对象的绑定方法与非绑定方法
绑定方法: 绑定的方法
1.对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法
2.类的绑定方法: 加了@classmethod装饰器的方法就是类的绑定方法
3.非绑定方法: 加了@staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数
@property 让函数方法 bmi() 变成属性,
@bmi.setter 和 @bmi.deleter 让这个函数方法 bmi() 可以进行属性一样的修改和删除,
所以 @bmi.setter 和 @bmi.deleter 装饰的函数方法名必须是property装饰的函数方法名bmi(),而不可以是随意定义的函数名字,如果换成其他名字会报错,显示的就是该属性(实际是个函数)无法进行修改或删除。
随意定义函数方法名是 类属性方法使用property 可以拥有的
class Foo:
# 绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参
def f1(self):
print(self)
@classmethod # 让被装饰的函数给类使用,约定俗称参数为cls
# 绑定给类的方法,类能使用,对象也可以使用,但是参数依然是类
def f2(cls):
print(cls)
# 什么都不绑定的,非绑定方法,定义了普通的函数
@staticmethod
def f3(self):
print(self)
f = Foo()
f.f1()
Foo.f1(1111)
print('*' * 50)
Foo.f2()
f.f2()
print('*'*50)
Foo.f3(2222)
f.f3(2222) # f为对象,但f3为普通函数,该传什么参就传什么参
<__main__.Foo object at 0x000002C80DCBC828>
1111
**************************************************
<class '__main__.Foo'>
<class '__main__.Foo'>
**************************************************
2222
2222
python 类的封装/property类型/和对象的绑定与非绑定方法的更多相关文章
- Python类总结-封装(Property, setter, deleter)
Property #property #内置装饰器函数,只在面向对象中使用 from math import pi class Circle: def __init__(self,r ): self. ...
- 孤荷凌寒自学python第二十三天python类的封装
孤荷凌寒自学python第二十三天python类的封装 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.从怎么样访问类的内部代码块中定义的私有属性说起 类中定义的私有属性和私有方法是无法被 ...
- 封装、property特性及绑定与非绑定方法
1.封装 (1)什么是封装? 封:属性对外是隐藏的,但对内是开放的: 装:申请一个名称空间,往里面装入一系列名字/属性 (2)为什么要封装? 封装数据属性的目的 首先定义属性的目的就是为了给类外部的使 ...
- python面向编程;类的绑定与非绑定方法、反射、内置方法
一.类的绑定与非绑定方法 ''' 类中定义函数分为了两大类: 1. 绑定方法 特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 绑定给对象的方法: 在类中定义函数没有被任何 ...
- python类的封装
Python之类的封装 1. 什么是封装 装:往容器/名称空间里存入名字 封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内(怎么做到的,在下文解释) 2. 为何要封装 封数据属性:不想要给 ...
- python类的封装与继承
封装 关注公众号"轻松学编程"了解更多. 1.概念 面向对象语言的三大特征:封装, 继承, 多态. 广义的封装: 类和函数的定义本身就是封装的体现. 狭义的封装:一个类的某些属性, ...
- Python类总结-封装(私有属性,方法)
封装基础 广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种封装 只让自己的对象能调用自己类中的方法 狭义上的封装-面向对象三大特性之一(私有变量,用公有的方法封装私有属性,方法叫封装) 把 ...
- python 面向对象(类的成员,属性,绑定和非绑定,)
面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实 ...
- Day08:继承与派生,多态,封装,绑定与非绑定方法,面向对象高级(反射,__str__,__del__)
上节课复习:1.编程思想 面向过程 核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么后干什么 基于该思想编写程序就好比在设计一条流水线,是一种机械式的思维 ...
随机推荐
- Codeforces Round #563 (Div. 2) B. Ehab Is an Odd Person
链接:https://codeforces.com/contest/1174/problem/B 题意: You're given an array aa of length nn. You can ...
- BZOJ2595(状压dp)
要点 设\(f[i][j][k]\)为经过点\((i,j)\)且包含点集\(k\)的最小代价,其中k是指景点集合的枚举. 考虑有两种情况:1.点\((i,j)\)作为关键点连接了两个子集时\(f[i] ...
- Cent OS 6.5 下 Node.js安装
打开官网 http://nodejs.org/ 点击那个绿色的INSTALL 按钮下载安装包,然后解压. 基本的环境我原本已经安装完毕,这是需求的环境,来源安装包中的README.md,需要的自行 ...
- ssis-oracle 数据流任务
[OLE DB 源 1 [16]] 错误: SSIS 错误代码 DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER.对连接管理器“F360DB”的 A ...
- mysql explain 的extra中using index ,using where,using index condition,using index & using where理解
using index :查找使用了索引,查询结果覆盖了索引 using where:查找使用了索引,不需要回表去查询所需的数据,查询结果是索引的一部分 using index condition:查 ...
- 集合、迭代器、增强for循环、泛型
1集合 集合是java中提供的一种容器,可以用来存储多个数据. 数组的长度是固定的.集合的长度是可变的.集合中存储的元素必须是引用类型数据. 1.1ArrayList集合存储元素(复习) 例: pub ...
- keil下JLINK在线调试仿真设置,SWD连接
keil下JLINK在线调试仿真设置,以下三个步骤搞定: 有时我们编译时会遇到空间不足的情况,首先我们应该把 flash和RAM的size 设置为当前所用芯片的大小,如下我使用了一个片上flash 2 ...
- java 通过文件后缀名查找文件
最近开发项目的时候需要过滤出一些指定的文件,所以有了以下的一些代码: /** **该类主要是过滤得到指定后缀名的文件 **/ public class DataFileFilter implement ...
- fiddler设置只抓取某一域名请求
简单易懂~
- Jenkins系列——使用Dashboard View分类展示作业
1.目标 创建的作业多了,在一个视图中展示多有不便.因此需要使用 Dashboard View 将作业按照后缀进行分类展示. 如下图,可以按照后缀添加CODE,TEST和OTHER视图. 2.环境说明 ...