博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python之面向对象进阶2
阅读量:5098 次
发布时间:2019-06-13

本文共 4526 字,大约阅读时间需要 15 分钟。

封装、property装饰器

封装分为3种情况:封装对象的属性、封装类的属性、封装方法。

封装对象的属性:(在属性名前加双下划线__)

class Person:    def __init__(self,height,weight,name,sex):        self.__height = height  #私有对象属性:不在外面调它        self.__weight = weight        self.__name = name        self.__sex = sex    def bmi(self):        return self.__weight / self.__height ** 2    def tell_height(self):        print(self.__height)    def tell_weight(self):        return self.__weight    def set_weight(self,new_weight):        if new_weight > 20:            self.__weight = new_weightegg = Person(1.7,125,'egon',None)egg.tell_height()#在类内调print(egg.__dict__)#查看类内的私有属性print(egg._Person__height)#在类外调用

通过私有属性后,我们可以更好的确保属性数值不会随意修改。

封装属性我们可以在set——weight里约束属性值得更改

class Person:    def __init__(self,height,weight,name,sex):        self.__height = height  #私有对象属性:不在外面调它        self.__weight = weight        self.__name = name        self.__sex = sex    def bmi(self):        return self.__weight / self.__height ** 2    def tell_height(self):        print(self.__height)    def tell_weight(self):        return self.__weight    def set_weight(self,new_weight):        if new_weight > 20:            self.__weight = new_weightegg = Person(1.7,125,'egon',None)egg.tell_height()#在类内调# print(egg.__dict__)#查看类内的私有属性print(egg._Person__height)#在类外调用egg.set_weight(105)print(egg.tell_weight())#私有属性:# 在本类内就可以正常调用# 在本类外就必须_类名__属性名调用,(不建议你调)

封装类的属性

class Goods:    __discount = 0.8  #类的私有属性    def __init__(self,name,price):        self.name = name        self.price = price    def goods_price(self):        return self.price * Goods.__discountbanana = Goods('banana',2)print(banana.goods_price())#类内调用# print(Goods.__dict__)#查看类的私有属性print(Goods._Goods__discount)#在类外调用私有属性

封装对象的方法

class Foo:    def __init__(self,height,weight):        self.height = height        self.weight = weight    def tell_bmi(self):        #体重/身高的平方        return self.weight / self.__heightpow()    def __heightpow(self):  #私有方法        return  self.height * self.heightegon = Foo(1.7,125)print(egon.tell_bmi())print(Foo.__dict__)print(egon._Foo__heightpow())  #类外调用方法#私有的:类属性 对象属性 方法#变成私有的 :__名字#在类内都是照常使用#在类外部就变形称为:_类名__名字#定义私有~的原因#不让外部的人瞎调,不让子类继承

封装的进阶

通过property装饰器把一个方法变成一个属性用

from math import piclass Circle:    def __init__(self,radius):        self.radius = radius    @property   #area = property(area)    def area(self):        return pi*self.radius*self.radius    @property    def perimeter(self):        return 2*pi*self.radiusc = Circle(10)print(c.area)print(c.perimeter) 我们调用area方法和perimeter方法就像调用属性一样

上个牛逼的代码(缓存网页的,用面向对象的方法)

from urllib.request import urlopenclass Web_page:    def __init__(self,url):        self.url = url        self.__content = None#私有对象属性    @property    def content(self):   #content 内容,相当于一个属性        if self.__content:  #做了一个什么转换  _Web_page__content            return self.__content        else:            self.__content = urlopen(self.url).read().decode(encoding='utf-8')  #做缓存            return self.__contentmypage = Web_page('http://www.baidu.com')print(mypage.content)print(mypage.content)

计算传入数据的值

#计算传入的数据的值class Num:    def __init__(self,*args):        print(args)        if len(args) == 1 and (type(args[0]) is list or type(args[0]) is tuple):            self.members = args[0]        else:            self.members = args    @property    def sum(self):        return sum(self.members)    @property    def average(self):        return self.sum/len(self.members)    @property    def min(self):        return min(self.members)    @property    def max(self):        return max(self.members)nums = Num([1,2,3])print(nums.sum)# print(nums.average)# print(nums.min)# print(nums.max)# num2 = Num(4,5,6)# print(num2.sum)# print(num2.average)# print(num2.min)# print(num2.max)

property装饰器(property、set、del方法)

class Goods:    __discount = 0.8  #类的私有属性    def __init__(self,name,price):        self.name = name        self.__price = price    @property    def price(self):      new_price=self.__price * Goods.__discount      return  new_price    @price.setter    def price(self,new_price):        if type(new_price) is int:            self.__price = new_price    @price.deleter    def price(self):        del self.__priceapple = Goods('apple',10)print(apple.price)apple.price = 20print(apple.price)

总结

#@property把一个类中的方法 伪装成属性#obj.func()#obj.func  -->属性#因为属性不能被修改#@funcname.setter,来修改#obj.func = new_value 调用的是被@funcname.setter装饰器装饰的方法#被@property装饰的方法名必须和被@funcname.setter装饰的方法同名#@funcname.deleter#在执行del obj.func 的时候会调用被这个装饰器装饰的方法(同名)

 

 

                                      

转载于:https://www.cnblogs.com/1a2a/p/7365625.html

你可能感兴趣的文章
Windows Phone开发(4):框架和页 转:http://blog.csdn.net/tcjiaan/article/details/7263146
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>
IOS-图片操作集合
查看>>
IO—》Properties类&序列化流与反序列化流
查看>>
jquery实现限制textarea输入字数
查看>>
Codeforces 719B Anatoly and Cockroaches
查看>>
ActiveMQ与spring整合
查看>>
第一阶段冲刺06
查看>>
EOS生产区块:解析插件producer_plugin
查看>>
排球积分程序(三)——模型类的设计
查看>>
HDU 4635 Strongly connected
查看>>
格式化输出数字和时间
查看>>
页面中公用的全选按钮,单选按钮组件的编写
查看>>
java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程
查看>>
(旧笔记搬家)struts.xml中单独页面跳转的配置
查看>>
不定期周末福利:数据结构与算法学习书单
查看>>
关于TFS2010使用常见问题
查看>>
URL编码与解码
查看>>