zoukankan      html  css  js  c++  java
  • Python 类 Property Staticmethod Classmethod

    前戏:

      一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。 

    而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。

    这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。 

    既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢?

    从它们的使用上来看:

      • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。

      • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

     

     

    # @property 属性方法

    属性方法的作用就是通过@property把一个方法变成一个静态属性

    class Foo(object):
        def __init__(self, name):
            self.name = name
    
        def func(self):
            print("%s:基本方法" %self.name)
    
        @property  # pro = property(pro)
        def pro(self):
            print("%s:属性方法" %self.name)
    
    foo_obj = Foo("alex")
    foo_obj.func()
    foo_obj.pro

    # @getter @setter @deleter

    class A(object):
    
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, value):
            if isinstance(value, str):
                self.__name = value
            else:
                raise TypeError("%s must be str" % value)
    
        @name.deleter
        def name(self):
            raise AttributeError("can not be delete")
    
    a = A("alex")
    print(a.name)
    a.name = 222
    del a.name

     

    总结:

    @property属性方法   封装类中的方法,给用户更加简单的调用方式,隐藏具体的实现细节。

    @method.getter  获取属性

    @method.setter  设置属性, 可以写更多逻辑(比如格式转换,类型判断),并提醒其他人这里面可能有magic

    @method.deleter 删除属性

      

     

    # @staticmethod

    (也可以看成是静态方法已经跟这个类没关系了,相当于已经脱离了这个类,是一个完全独立的函数,只是调用的时候必须通过这个类, 或者为了规范代码而将函数放到类中)

    (类中定义函方法 PyCharm 提示Method xxx may be ‘static’, 原因是该方法不涉及对该类属性的操作,编译器建议声明为@staticmethod,面向对象思想体现)

    利用staticmethod来实现多种实例化方式

    import time
    
    class Date(object):
        def __init__(self, year, month, day):
            self.year = year
            self.month = month
            self.day = day
    
        @staticmethod
        def now():
            t = time.localtime()
            return Date(t.tm_year, t.tm_mon, t.tm_mday)
    
    date = Date.now()
    print(date.year, date.month, date.day)

    date = Date(1999,12,12)

     

    # @classmethod

    类方法只能访问类变量,不能访问实例变量, 也就是跟类有关,跟实例无关。

    class ParentClass(object):
        var = "test for parent"
    
        @classmethod
        def clsmethod(cls):
            print(cls.var)
    
    class SubClass(ParentClass):
        var = "test for sub"
    
    ParentClass.clsmethod()
    >>>
    test for parent
    SubClass.clsmethod()
    >>>
    test for sub

    此时ParentClass.clsmethod输出为 “test for parent”,而Subclass.clsmethod输出为“test for sub”。

    通过此比较很好的诠释了@classmethod类方法隐式传入的第一个参数是当前类,而不是父类。

    同时类方法操作的是class 类对象提供的内部信息。而staticmethod可以作为一般的工具函数来使用。

     

    总结:

    Classmethod主要用途是作为构造函数;

      Python只有一个构造函数__new__,如果想要多种构造函数就很不方便。只能在new里面写一堆if isinstance 。
      有classmethod之后就可以用classmethod来写不同的构造函数,cpython里面大部分classmethod最后都是 return cls(XXX), return XXX.__new__ ()之类的。

    Staticmethod主要用途是限定Namespace;

      也就是说这个函数虽然是个普通的function,但是它只有这个class会用到,不适合作为module level的function,这时候就把它作为staticmethod。
      如果不考虑namespace的问题的话直接在module里面def function就行了。

     

  • 相关阅读:
    12.extern(转)
    QT错误笔记-Qt Creator needs a compiler set up to build. Configure a compiler in the kit options.
    11.static(转)
    C/C++ 错误笔记-在给结构体中的指针赋值时,要注意该指针是否已指向内存空间
    10.动态库
    【转载】pygame的斜线运动
    题解-python-CodeForces 227B
    题解-python-CodeForces 227A
    【笔记】Python简明教程
    Pyhton核心编程-Chap2习题-DIY
  • 原文地址:https://www.cnblogs.com/vincenshen/p/6500627.html
Copyright © 2011-2022 走看看