python中封装的作用_[ python ] 封装

类中的私有属性

在类中定义一个私有属性如下:

classPerson(object):def __init__(self, name):

self.__name = name #定义私有属性 self.__name

p= Person('hkey')print(p.__name) #外部不能直接调用私有属性

执行结果:

Traceback (most recent call last):

File"E:/learn_python/day26/test6.py", line 11, in

print(p.__name)

AttributeError:'Person' object has no attribute '__name'

私有属性的使用场景:

隐藏起一个属性,不想让类的外部调用

想要保护这个属性,不想让属性随便被改变

保护这个属性,不被子类继承

虽然私有属性不能直接从外部调用,但是我们可以通过对象.__dict__ 尝试来获取这个属性试试:

classPerson(object):def __init__(self, name):

self.__name =name

p= Person('hkey')print(p.__dict__)print(p._Person__name)

执行结果:

{'_Person__name': 'hkey'} #执行 p.__dict__ 会直接获取对象的属性和方法

hkey #在外部可以通过 p._Person__name 来获取类中的私有属性

使用对象通过 _类名__属性名 来获取属性的方式并不推荐,在python中没有强制不允许查看类中私有属性,一切都靠自觉;

将类中的方法当作属性查看修改删除

property  将方法变成属性

一个实例: 写一个类,计算圆的周长和面积

from math importpiclassCircle(object):def __init__(self, r):

self.__r =rdef per(self): #圆的周长

return 2*pi*self.__r

def area(self): #圆的面积

return pi * self.__r **2c= Circle(5)print(c.area())print(c.per())

在上面的代码中,我们要计算圆的周长和面积,都是通过对象.方法名() 去获取的。当我们使用 property 可以通过 对象.属性名 的方式调用函数内的方法,如下:

from math importpiclassCircle(object):def __init__(self, r):

self.__r =r

@property#通过装饰器的形式,将类中方法调用的方式修改为函数调用的方式

defper(self):return 2*pi*self.__r@propertydefarea(self):return pi * self.__r **2c= Circle(5)print(c.area)print(c.per)

属性可以重新赋值,但是当使用 property 转换为属性调用的方式后,是不能直接赋值的。

classPerson(object):def __init__(self, name):

self.__name =name

@property#使用 property 改变类中函数的调用方式

defname(self):return self.__name + 'run.'p= Person('hkey')print(p.name)

setter

当我们要修改对象 p 的 name 属性时,就需要使用 setter

classPerson(object):def __init__(self, name):

self.__name =name

@propertydefname(self):return self.__name + 'run.'@name.setter#使用 setter 装饰器

defname(self, new_name):

self.__name =new_name

p= Person('hkey')print(p.name)

p.name= 'xiaofei' #就可以实现从新赋值

print(p.name)

当使用 setter 时, 我们要明确命名规则:

当使用 setter 时,我们不仅可以赋值,还可以做一些判断

classPerson(object):def __init__(self, name):

self.__name =name

@propertydefname(self):return self.__name + 'run.'@name.setterdefname(self, new_name):if new_name.isalpha(): #new_name 必须是有字母或汉字组成

self.__name =new_name

p= Person('hkey')print(p.name)

p.name= '123' #字符串是由数字组成,赋值失败

print(p.name)

deleter

这个组合中最不常用的装饰器:

作用:当要删除类中某个属性的时候使用 deleter 具体使用如下

classPerson(object):def __init__(self, name):

self.__name =name

@propertydefname(self):return self.__name + 'run.'@name.setterdefname(self, new_name):if new_name.isalpha(): #new_name 必须是有字母或汉字组成

self.__name =new_name

@name.deleterdefname(self):print('\033[31;1m我要删除类中【__name】属性了.\033[0m')del self.__namep= Person('hkey')delp.name

执行结果:

我要删除类中【__name】属性了.

一个实例, 商品打折的例子。

classGoods(object):

dicount= 0.5

def __init__(self, name, price):

self.name=name

self.__price =price

@propertydefprice(self):return self.__price *Goods.dicount

apple= Goods('apple', 10)

pear= Goods('pear', 5)print(apple.price)print(pear.price)

在上面的实例中,当要改变所有商品的折扣时,只需要修改 dicount, 所有商品的折扣都会改变了。

classmethod 类方法

当要使用类方法时,需要满足以下两点:

把一个方法变成一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象

当一个方法的操作只涉及静态属性的时候,就应该使用 classmethod来装饰这个方法

还是上面商品打折的例子:

dicount 是一个类属性,我们就可以通过定义一个类方法来修改这个属性

classGoods(object):

dicount= 0.5

def __init__(self, name, price):

self.name=name

self.__price =price

@propertydefprice(self):return self.__price *Goods.dicount

@classmethod#定义一个类方法

def modify_discount(cls, new_discount): #cls: 类名,普通形参

cls.dicount =new_discount

apple= Goods('apple', 10)

pear= Goods('pear', 5)

Goods.modify_discount(0.2) #打 0.2 折 # 调用方式 类名.类方法(普通形参)

print(apple.price)print(pear.price)

执行结果:2.0

1.0

staticmethod 静态方法

在完全面向对象的程序中,如果一个函数即和对象没有关系,也和类没有关系。那么就用 staticmethod 将这个函数变成一个静态方法

比如在纯面向对象的编程中,编写一个用户登录的类:

classLogin(object):def __init__(self, user, pwd):

self.user=user

self.pwd=pwddeflogin(self):pass@staticmethod#静态方法虽然是在类中,和类是完全无关的;

defget_user_pwd():

user= input('输入用户名:')

pwd= input('输入密码:')

Login(user, pwd)

Login.get_user_pwd()#进行登录

使用类方法和静态方法要注意以下几点:

类方法和静态方法 都是类调用的

对象可以调用类方法和静态方法,但是一般建议使用类名去调用

类方法有一个默认参数 cls 代表这个类,静态方法 没有默认的参数 就像函数一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值