类中的三个装饰器方法

@classmethod

class A:
    __count = 0 #隐藏count属性
    def __init__(self,name):
        self.name = name
        self.__add_count() #每一次实例化的时候调用私有化__count进行累加
    def __add_count(self): #定义一个私有化的方法
        A.__count +=1
    def show_count(self): #定义一个普通方法
        return A.__count  #让用户可以从外部查看__count的值
    def eat(self):
        print('%s在吃饭'%self.name)
wl = A('wanglan')
print(wl.show_count())
wl.eat()
#有的时候,在类中会有一种情况,就是这个方法并不需要使用某一个对象的属性,因此,这个方法中的self参数是一个完成无用的参数,
#show_count是一个查看类中属性的方法,这样的方法和某一个对象并没有直接联系

在上面代码中,__add_count 方法和show_count方法并没有使用self参数,但是我们给它传了,正常情况下,如果参数不被使用,我们不应该传入改参数,因此这个方法中的self参数是一个完全无用的参数,我们可以直接删除,删除后的报错也只是Pycharm上的语法报错,但是python的语法不希望我们这样做,我们可以使用 @classmethod 装饰器来解决

class A:
    __count = 0 #隐藏count属性
    def __init__(self,name):
        self.name = name
        self.__add_count() #每一次实例化的时候调用私有化__count进行累加
    @classmethod   #被classmethod 装饰器装饰的方法,都用一个默认的参数,这个参数就是当前类
    def __add_count(cls): #定义一个私有化的方法
        print(cls,A)  #两个值相同
        cls.__count +=1 # cls 就可以取代A
    @classmethod
    def show_count(cls): #定义一个普通方法
        return cls.__count  #让用户可以从外部查看__count的值
    def eat(self):
        print('%s在吃饭'%self.name)
print(A.show_count()) #可以直接调用show_count
wl = A('wanglan')
print(wl.show_count())
wl.eat()

结果:
0
<class '__main__.A'> <class '__main__.A'>
1
wanglan在吃饭

本质上:一个方法不用对象属性但是使用静态属性 -- 类方法(@classmethod)

某一个方法被创造出来,就是为了对静态变量进行操作,根部不涉及到对象,所以这个方法就应该被定义成:类方法(被@classmethod装饰),调用这个类方法时,可以使用对象调用wl.show_count(),也可以使用类调用 A.show_count(),但是这个方法的默认参数永远是当前类的命名空间,而不是对象

 @staticmethod

def login():  #普通函数
    pass
login() #调用

纯面向对象编程

class User(object):
    @staticmethod
    def login(): #是User类中的名字 函数的名字 login就是一个类中的静态方法,本质上就是一个函数
        pass
ret = User.login()

如果一个类中的方法不用对象属性也不用静态熟属性 -- 静态方法(@staticmethod),实际上这个方法就是一个普通的函数

小结

               普通的方法             类方法              静态方法
默认参数          self                 cls                无
操作的变量        操作对象的属性          操作静态属性         既不操作对象属性,也不操作类的属性
所属的命名空间     类                    类                 类
调用方式          对象                  类/对象             类/对象
对应的装饰器       无                   @classmethod       @staticmethod

@property:

把一个方法伪装成属性,和调用属性一样去调用方法()名称装饰,动词就不用了)

某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性

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

    @property  # 把一个方法伪装成属性 源码中有人写,
    def area(self):   # 被property装饰器装饰的方法不能传递除self以外的参数
        return pi*self.r**2

    @property
    def perimeter(self):
        return self.r*pi*2

c1 = Circle(5)
# print(c1.area()) #加入@property 方法前的调用
print(c1.area) #加入@property 方法后的调用
c1.r = 10
print(c1.area)

某一个属性需要被私有化,又需要能被外部查看,这种情况,把这个属性通过方法返回,方法伪装成属性

class Person:
    def __init__(self,name):
        self.__name = name  # 不让外面随便修改

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

wl = Person('wanglan')
print(wl.name)

修改属性值

class Person:
    def __init__(self,name):
        self.__name = name  # 不让外面随便修改

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

    @name.setter   # 之前必须有一个同名的方法被property装饰过
    def name(self,new_name):
        if type(new_name) is str:
            self.__name = new_name

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


wl= Person('wang')
print(wl.name)
wl.name = 'wanglan'
print(wl.name)
del wl.name   # 只是相当于调用被deleter装饰的方法,并不相当于删除name属性
print(wl.name)

猜你喜欢

转载自www.cnblogs.com/wanglan/p/10022222.html
今日推荐