python封装类型_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': , 'f2': , '__dict__':

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为普通函数,该传什么参就传什么参

1111

**************************************************

**************************************************

2222

2222

内容来源于网络如有侵权请私信删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值