Python全栈学习笔记day 26:封装、property、classmethod、staticmathod

一、封装

【封装】隐藏对象的属性和实现细节,仅对外提供公共访问方式。

【私有变量】: __名字    (称为私有化)

          私有化了之后,就不能能从类的外部直接调用了。

          静态属性、方法、对象属性都可以私有化,这种私有化只是从代码级别做了变形,并没有真的约束。

用到私有的场景 :

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

2.我想保护这个属性,不想让属性随意被改变

3.我想保护这个属性,不被子类继承

私有化后的调用:

class Person:
    __key = 123                   私有静态属性
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd    私有属性

    def __get_pwd(self):          私有方法
        return self.__passwd      只要在类的内部使用私有属性,就会自动的带上_类名

    def login(self):              正常的方法调用私有的方法
        self.__get_pwd()

alex = Person('alex','alex3714')
print(alex._Person__passwd)        _类名__属性名
print(alex.get_pwd())
  对象的私有属性、类中的私有方法、类中的静态私有属性:所有的私有的 都不能在类的外部使用

封装使用栗子:

class Room:
    def __init__(self,name,length,width):
        self.__name = name
        self.__length = length
        self.__width = width
    def get_name(self):
        return self.__name
    def set_name(self,newName):               改名字
        if type(newName) is str and newName.isdigit() == False:
            self.__name = newName
        else:
            print('不合法的姓名')
    def area(self):                            面积
        return self.__length * self.__width

jin = Room('金老板',2,1)
print(jin.area())             2
jin.set_name('2')            不合法的姓名
print(jin.get_name())        金老板

这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了(原则上不允许)

二、property

内置装饰器函数,只在面向对象中使用
可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值

使用栗子:

当不使用@property时:

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r

    def perimeter(self):           圆的周长
        return 2*pi*self.r
    
    def area(self):                圆的面积
        return self.r**2*pi

c1 = Circle(5)
print(c1.area)               <bound method Circle.area of <__main__.Circle object at 0x008DF150>>
print(c1.perimeter)          <bound method Circle.perimeter of <__main__.Circle object at 0x008DF150>>

当使用@property时:

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r

    @property
    def perimeter(self):                圆的周长
        return 2*pi*self.r

    @property
    def area(self):                     圆的面积
        return self.r**2*pi

c1 = Circle(5)
print(c1.area)                          78.53981633974483
print(c1.perimeter)                     31.41592653589793
注意:此时的特性area和perimeter不能被赋值
c.area=3                 为特性area赋值
'''
抛出异常:
AttributeError: can't set attribute
'''

2.1  @方法名.setter(对类的对象修改)

使用栗子:

class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):
        return self.__name + 'sb'
    @name.setter
    def name(self,new_name):
        self.__name = new_name

tiger = Person('泰哥')
print(tiger.name)                    泰哥sb
tiger.name = '全班'
print(tiger.name)                    全班sb

使用格式:

2.2  @price.deleter(对类的对象删除)

栗子:

class Goods:

    def __init__(self):
        self.original_price = 100
        self.discount = 0.8

    @property
    def price(self):                            实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price


obj = Goods()
obj.price                  获取商品价格
obj.price = 200            修改商品原价
print(obj.price)
del obj.price              删除商品原价

三、classmethod 类方法

作用:把一个方法 变成一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象
使用情况:当这个方法的操作只涉及静态属性的时候 就应该使用classmethod来装饰这个方法
class Goods:
    __discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod
    def change_discount(cls,new_discount):   修改静态属性:折扣
        cls.__discount = new_discount
apple = Goods('苹果',5)
print(apple.price)
Goods.change_discount(0.5)   
print(apple.price)

类方法:有一个默认参数 cls 代表这个类 cls

四、staticmathod  静态的方法

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

栗子:

class Login:
    def __init__(self,name,password):
        self.name = name
        self.pwd = password
    def login(self):pass

    @staticmethod
    def get_usr_pwd():   # 静态方法
        usr = input('用户名 :')
        pwd = input('密码 :')
        Login(usr,pwd)

Login.get_usr_pwd()

静态方法:没有默认的参数 就象函数一样

对象可以调用类方法和静态方法么?   
    可以,一般情况下 推荐用类名调用

猜你喜欢

转载自blog.csdn.net/qq_35883464/article/details/83751009