zoukankan      html  css  js  c++  java
  • python之面向对象进阶2

    封装、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_weight
    
    egg = 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_weight
    
    egg = 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.__discount
    
    banana = 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.height
    
    egon = Foo(1.7,125)
    print(egon.tell_bmi())
    print(Foo.__dict__)
    print(egon._Foo__heightpow())  #类外调用方法
    
    #私有的:类属性 对象属性 方法
    #变成私有的 :__名字
    #在类内都是照常使用
    #在类外部就变形称为:_类名__名字
    
    #定义私有~的原因
    #不让外部的人瞎调,不让子类继承

    封装的进阶

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

    from math import pi
    class 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.radius
    c = Circle(10)
    print(c.area)
    print(c.perimeter)
    我们调用area方法和perimeter方法就像调用属性一样

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

    from urllib.request import urlopen
    class 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.__content
    
    mypage = 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.__price
    
    apple = Goods('apple',10)
    print(apple.price)
    apple.price = 20
    print(apple.price)

    总结

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

     

                                          

  • 相关阅读:
    几种常见的软件体系结构及特点分析
    mvc模式
    代理模式 补充
    软件架构体系风格
    大道至简之编程的精义读后感-Java伪代码
    MVC架构模式实例
    浅谈模型-视图-控制器模式
    《大型网站技术架构:核心原理与案例分析》读后感
    质量属性分析
    构架漫谈读后感之软件架构师的工作
  • 原文地址:https://www.cnblogs.com/1a2a/p/7365625.html
Copyright © 2011-2022 走看看