类中的方法分类及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>  返回的是函数类型的地址

类方法,普通方法,静态方法的区别

# 类方法,静态方法,普通方法的区别
class A():
   @classmethod
   def clas(cls):    # 定义一个类方法
      print('clas')

   def common(self):   # 普通方法
      print('common')

   @staticmethod
   def sta():    # 静态方法
      print('sta')


A.clas()  # clas  类名直接调用类方法,不用传参,默认参数是类名
A().clas()  # clas  类的实例化对象也可以调用类方法

A.common('aa')  # common  类名直接调用普通方法,必须传参,self
A().common()  # common    当对象调用普瑞方法时,不用传参。因为self就是实例化对象,默认吧自己穿给了self。

A.sta()  # sta  类名调用静态方法
A().sta()  # sta  对象调用静态方法,都不用传参

类中定义的函数什么情况下是方法method,什么情况下是函数function

class Foo:
    School = 'xihu'
    Country = 'China'
    language = 'Chiness'

    @classmethod
    def class_method(cls):
        print(cls.School)

    @staticmethod
    def static_method():
        print('in staticmethod')

    def common(self):
        print('in common')
f = Foo()

print(Foo)  # <class '__main__.Foo'>  类Foo的再内存上的地址

print(f.common)   # <bound method Foo.common of <__main__.Foo object at 0x000002CC931ABA20>>  对象调用普通方法 : method
print(Foo.common)  # <function Foo.common at 0x000001A4DD69CC80>  类名调用普通方法 : function

print(Foo.static_method)  # <function Foo.static_method at 0x000002A774F7CD08>   类名调用静态方法: function
print(f.static_method)  #  <function Foo.static_method at 0x000002482175CD08>  对象调用静态方法:function

print(f.class_method)   # <bound method Foo.class_method of <class '__main__.Foo'>>  对象调用类方法  method
print(Foo.class_method)  # <bound method Foo.class_method of <class '__main__.Foo'>>  类调用类方法 method
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值