美文网首页
lesson 041 —— 静态属性

lesson 041 —— 静态属性

作者: 爱喵喵的鱼 | 来源:发表于2019-02-11 17:02 被阅读0次

    lesson 041 —— 静态属性

    静态属性

    我们知道类既有函数属性又有数据属性,实例只有数据属性,我们在使用实例调用类的函数属性并运行时,总要带上函数后面的括号才能运行,不然总是调用函数的内存地址。那么我们如何能像调用数据属性一样调用函数属性呢?

    类中提供了 @property 关键字,可以看成 @property 是一个装饰器,装饰器的作用是调用类的函数属性 key 值时,直接来运行该 key 值对应的函数。像是调用类的属性一样来直接调用并运行类的函数。

    注意: 当类中的函数有其他参数时(非 self ),加上 @property 关键字会报错,提示缺少必要的位置参数。可以判断,@property的作用是:直接运行被装饰的函数,不能带参数。

    class Door:
        address = "地球"
    
        def __init__(self,size,color,type):#构造函数
            self.size = size
            self.color = color
            self.type = type
    
        @property
        def open(self):
            "门打开的方法"
            print("这个%s门打开了" %self.type)
    
        @property
        def off(self,time):
            "门关闭的方法"
            print("这个%s门关闭了,时间为;%d" %(self.type,time))
    
    door1 = Door(16, 'red', '木门')
    
    #调用数据属性
    print(door1.size)
    print(door1.address)
    
    #调用函数属性
    # door1.open()    #函数后面的括号每次都必须要带上
    
    #实例调用类的静态属性
    print(Door.__dict__)
    door1.open
    #door1.off   # 报错,提示缺少一个参数time
    #door1.off(30)   # 报错
    

    结果

    16
    地球
    {'__module__': '__main__', 'address': '地球', '__init__': <function Door.__init__ at 0x7f5d6d43cbf8>, 'open': <property object at 0x7f5d6d4e31d8>, 'off': <property object at 0x7f5d6d4e33b8>, '__dict__': <attribute '__dict__' of 'Door' objects>, '__weakref__': <attribute '__weakref__' of 'Door' objects>, '__doc__': None}
    这个木门门打开了12
    

    类方法

    如果要求,不进行实例化,直接调用类的函数,此时会提示缺少必要的位置参数self。

    class Door:
        address = "地球"
    
        def __init__(self,size,color,type):#构造函数
            self.size = size
            self.color = color
            self.type = type
    
        def open(self):
            "门打开的方法"
            print("这个%s 生产的门打开了" %self.address)
    
        def off(self,time):
            "门关闭的方法"
            print("这个%s 生产的门关闭了,时间为;%s" %(self.address,time))
    
    # 不传参数调用
    Door.open()   # 报错,提示说缺少参数 self
    
    # 随意传一个参数调用
    Door.open('山东') # 报错,提示说 str 类没有 addess 的属性
    

    我们加上参数后,仍然报错。虽然我们可以随意加上位置参数,但是注意到此处的 self 有特殊含义,它是指实例的本身,也就是说要使用 self 必须要先实例化才行。为了解决这个问题,我们引入另一个 @classmethod 装饰器后,就可以直接通过类来调用类的函数属性了(该函数带类的数据属性参数),如下所示:

    class Door:
        address = "地球"
    
        def __init__(self,size,color,type):#构造函数
            self.size = size
            self.color = color
            self.type = type
    
        @classmethod
        def open(cls):
            # cls 是 Python 推荐的形参
            "门打开的方法"
            print("这个%s 生产的门打开了" %cls.address)
            cls.off(cls, 20)   # 这个是把类作为参数传进去了
    
        def off(self,time):
            "门关闭的方法"
            print("这个%s 生产的门关闭了,时间为;%s" %(self.address,time))
    
    Door.open()
    
    # 对象调用类方法
    d1 = Door(16, 'red', 'wood')
    d1.open()
    
    # 结果
    这个地球 生产的门打开了
    这个地球 生产的门关闭了,时间为;20
    这个地球 生产的门打开了
    这个地球 生产的门关闭了,时间为;20
    

    注意: 类方法与对象的属相没有关系,虽然对象可以调用类方法,但是,类方法里面使用的,都是类的属性,与对象属性没有关系。

    静态方法

    如果要求: 在类中定义一个函数,要求该函数中的位置函数与实例无关,与所在的类本身也无关。为了解决该问题,现引入了 @staticmethod

    class Door:
        address = "地球"
        
        def __init__(self,size,color,type):#构造函数
            self.size = size
            self.color = color
            self.type = type
            
        def open(self):
            print("这个%s门打开了" %self.type)
            
        def off(self,time):
            print("这个%s门关闭了,时间为;%s" %(self.type,time))
            
        @staticmethod
        def test(x,y):
            print("%s,%s的乘积为:%s"%(x,y,x*y))
    
        def test1(x,y):
            print("%s,%s的乘积为:%s"%(x,y,x*y))
    
    door1 = Door(16, 'red', '木门')
    
    #调用静态方法test
    Door.test(1,3)
    door1.test(2,5)
    
    #调用常规方法test1
    Door.test1(1,3)
    door1.test1(2,5)    # 报错,说只有两个参数,但是传进来了三个参数
    

    可以看出,虽然 test 方法与实例无关,与类本身也无关,但是却可以通过实例和类来调用它,却使用实例调用它是不会传入实例本身的位置参数(在正常类方法中,实例化类后,实例在调用它时,会自动默认首先传入实例本身即 self )。

    为什么不能直接在类中定义一个函数,不传 self 形参?按照上面的提议是否能满足实例可以调用,类本身也可以调用的要求呢?原因很简单,self 只是一个形参,和一般函数形参一样,只是约定成俗的使用 self,使用其它的形参也是可以的。

    我们可以看出,如果直接在类中定义一个常规方法(不含self的形参),通过类本身访问它,但是通过实例来访问它时虽然也是传入2个参数,但是实际行python自动默认首位传入了self,这样就造成了上面的情况了(传的是2个参数,收到的是3个参数)

    注意: 静态方法中不能调类属性和方法,也不能调用实例变量,只是类的工具包。因为没有self,也就不能指类本身或实例本身,从而不能调用相应的类属性和类方法。

    相关文章

      网友评论

          本文标题:lesson 041 —— 静态属性

          本文链接:https://www.haomeiwen.com/subject/ohgqeqtx.html