类中的方法分类及propety,classmethod,staticmethod 装饰器

类空间中有:
- 静态属性: 所有对象动统一拥有的属性
- 方法
- 类方法 :不使用类中的命名空间也不使用对象的命名空间:一个普通函数,没有默认参数 ,cls 表示类 self 表示对象
- 静态方法
- property方法

  • property方法
property 装饰器 保护一个变量,在修改的时候能够添加一些保护条件, 相对于C++来说,C++每个变量都会设置输入的类型和改动时的类型。而python只是在加了property装饰器的时候限制了类型。
setter 装饰器  1,被property装饰的方法, 2 实现了一个同名方法 3 被setter装饰器装饰了 4 该方法名放setter前。 4个条件才能用setter装饰器


例1class Student:

    def __init__(self, name):
        self.__name = name  # 把name设置为私有属性,为了不让不让看和改动

    @property   # 把name这个方法伪装成了属性,property是属性的意思,这样也可以用通常的方法看到name这个属性一样,只是不可以改
    def name(self):  # 装饰器一定要紧挨着此方法,中间不能有换行
        return self.__name

    @name.setter  # 改name的操作在这一步,限制了条件,这样就不可以随便更改此私有属性。
    def name(self, new):
        if type(new) is str:
            self.__name = new


linda = Student('linda')

print(linda.name)  # linda  # 直接打印了name方法返回的值

linda.name = 'laura'  # 修改name的值,实际是执行了被setter装饰的方法,因为被装饰器property装饰了,所以修改的时候,用通常
修改属性的方法就可以,因为要规范代码的格式,如果要删除私有属性,总不能还价格类名在加个双下划线把,python的语法就是优美,简洁。

print(linda.name)  # laura2class A:
    def __init__(self, name):
        self.name = name

    @property
    def func(self):
        return self.name

    @func.setter
    def func(self, new):  # 修改
        self.name = new

    @func.deleter
    def func(self):
        del self.name

a = A('laura')
print(a.func)   # laura # 执行被property伪装的方法
print(a.__dict__)  # {'name': 'laura'}
a.func = 123  # 修改name
print(a.func)  # 123
print(a.__dict__)  # {'name': 123}
del a.func   # 删除一个property属性的时候会执行deleter装饰的方法
print(a.__dict__)


例3

class Goods:
    __discount = 0.8  # 私有变量,折扣不想让顾客看到

    def __init__(self, price):
        self.__price = price  # 价格也不想让顾客看见
        self.name = 'apple'

    @property  # 将price这个伪装成属性, 因为想让顾客看到我设置的价格
    def price(self):
        return self.__price * Goods.__discount

    @price.setter
    def price(self, new):
        if new is int:   # 如果改动后的价格是整数
            self.__price = new   # 就可以更改,否则price还是原来的不变
        print(self.__price)   # 打印改动后的价格

    @price.deleter   # 如果想删除该变量,通常格式是在类外面是删除不了的,所以设置了一个方法,用来删除变量。
    def price(self):
        self.__price = 50
        del self.__price

apple = Goods(10)

print(apple.price)  # 8.0

print(apple.__dict__)  # {'_Goods__price': 10, 'name': 'apple'}

del apple.price   # 删除price这个对象的私有属性,实际是执行了被deleter装的方法,由于被装饰成了属性,所以删除的格式也像删除属性的方法,
print(apple.__dict__)  # {'name': 'apple'}

del apple.name  # 此代码就是正常的删除对象空间的普通的属性。

print(apple.__dict__)  # {}

'''
综上所述,一个方法被伪装成属性之后,应该可以执行一个属性的增删改查的操作,
增加和修改,对应setter装饰的方法,这个方法有一个必传的参数,表示赋值的时候等号后面的值
删除一个属性,对应着被deletter装饰的方法,这个方法并不能在执行的时候真的删除这个属性。
而是在代码中执行了什么就有什么效果,就是说实际上本质还是一个函数,函数本身是不能增删改查,而是
函数代码块有什么,函数就执行什么。
'''
  • @classmethod 类方法 只使用类中的资源,且这个资源可以直接用类名引用和使用,那这个方法应该被该为类方法
class Goods:
    pass
    __discount = 0.8
    def __init__(self, price):
        self.__price = price
        self.name = 'apple'

    @classmethod   # 类方法 如果类中的私有属性,如折扣,不想让别人看到,或改动的时候不想通过类名直接改,而是要加一些限制条件,那可以定义一个函数去改,而如果定义一个函数,那必然要传一个对象的self参数,这是python底部已经设置好的,那我不想传对象这个参数,直接传我要改动的新值就好了,类方法可以解决这件事情,默认传了的参数是类名
    def change_discount(cls, new):
        cls.__discount = new

Goods.change_discount(0.7)
print(Goods.__dict__)

apple = Goods(10)
banana = Goods(20)
apple.change_discount(0.7)
print(apple.price)

  • @staticmethod 静态方法

class Student:

    @staticmethod  # 静态方法 static 静止的 被staticmethod装饰过的方法变成了普通函数
    def login():
        print('IN LOGIN')

a = Student()

a.login()  # IN LOGIN # 可以被对象调用

Student.login()  # IN LOGIN # 可以被类名调用


  • 判断是否是类中的方法还是普通函数

class Foo():
    @classmethod
    def class_method(cls):
        pass

    @staticmethod
    def static_method(): pass

from types import MethodType, FunctionType

obj = Foo()

print(isinstance(Foo.class_method, MethodType))  # True 判断class_method 是不是方法类型

print(isinstance(Foo.static_method, FunctionType))  # True  判断static_method 是不是函数类型

print(obj.static_method)  # <function Foo.static_method at 0x000002244107ABF8>  返回的是函数类型的地址

猜你喜欢

转载自blog.csdn.net/weixin_42233629/article/details/82286860
今日推荐