python之property,classmethod,staticmethod

property属性

什么是特性property

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值,就是以前我们要调用方法,形式是对象.方法名(),有了这个属性就可以直接以调用属性的方式进行调用

property装饰的bmi仍然是一个方法 存在Person.dict
对象的.__dict__中不会存储这个属性

在一个类加载的过程中,会先加载这个中的名字,包括被property装饰的

在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性,
如果有就不能再在自己对象的空间中创建这个属性了
例一:人体的BMI指数:

class Person():
    def __init__(self, name, weight, height):
        self.name = name
        self.__height = height
        self.__weight = weight
    @property
    def cal_BIM(self):
        return self.__weight/self.__height ** 2
p = Person('dear', 65, 1.73)
print(p.cal_BIM)

例二:圆的面积

import math
class Circle:
    def __init__(self, r):
        self.r = r
 
    @property
    def area(self):
        return self.r **2 * math.pi
 
    @property
    def perimeter(self):
        return self.r *2 * math.pi
c=Circle(10)
print(c.r)
print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c.perimeter) #同上

#注意:此时的特性area和perimeter不能被赋值
c.area=3 #为特性area赋值
‘’’
抛出异常:
AttributeError: can’t set attribute
‘’’
为什么要用property

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

ps:面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开
但是Python中只有两种,【public】,【private】

python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现。
一个静态属性property本质就是实现了get,set,delete三种方法

class Person:
    def __init__(self, name):
        self.__name = name  #私有属性
    @property
    def name(self):
        return self.__name
 
    # 方法伪装成的属性的修改
    @name.setter
    def name(self, new_name):
        if type(new_name) is str:
            self.__name = new_name
        else:
            print('您提供的姓名数据类型不合法')
 
    # 方法伪装成的属性的删除
    @name.deleter
    def name(self):
        del self.__name
p = Person('happy')
print(p.name)      #执行def name(self):
p.name = 'like'   #修改名字,执行def name(self, new_name):
del p.name   #执行了被@name.deleter装饰的函数

具体实例用法:

# 商品的 折扣
# 有一个商品 : 原价 折扣
# 当我要查看价格的时候 我想看折后价
class Goods:
    def __init__(self, name, origin_price, discount):
        self.name = name
        self.__price = origin_price
        self.__discount = discount
 
    @property
    def price(self):
        return self.__price * self.__discount
    @price.setter
    def price(self, new_price):
        if type(new_price) is int or type(new_price) is float:
            self.__price = new_price
 
 
apple = Goods('apple',5,0.8)
print(apple.price)
# # 修改苹果的原价
apple.price = 8
print(apple.price)

作用:
将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性

将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性

classmethod

# 店庆 全场八折
class Goods:
    __discount = 0.8
    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price
 
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod
    def change_discount(cls, new_discount):     # 类方法可以直接被类调用 不需要默认传对象参数 只需要传一个类参数就可以了
        cls.__discount = new_discount
 
apple = Goods('apple',5)
banana = Goods('banana',8)
print(apple.price)
print(banana.price)
#折扣变了
Goods.change_discount(1)       # 不依赖对象的方法 就应该定义成类方法 类方法可以任意的操作类中的静态变量
print(apple.price)
print(banana.price)

staticmethod

当一个方法要使用对象的属性时 就是用普通的方法
当一个方法要使用类中的静态属性时 就是用类方法
当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法

class Student:
    def __init__(self,name):pass
 
    @staticmethod
    def login( a ):                   # login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可
        user = input('user :')
        if user == 'haha':
            print('success')
        else:
            print('faild')
Student.login(1)

猜你喜欢

转载自blog.csdn.net/qq_38362416/article/details/83960020