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就行了。

     

  • 相关阅读:
    Eclipse安装Hadoop插件
    (转)Ubuntu14.0.4中hadoop2.4.0伪分布模式配置
    Hadoop--DataNode无法启动
    启动与关闭hadoop
    hadoop中执行命令时发生错误
    strings命令
    Deriving data from ElasticSearch Engine
    elasticsearch data importing
    reading words in your computer and changing to female voice, linux festival text2wave saving wav files
    DDNS client on a Linux machine
  • 原文地址:https://www.cnblogs.com/vincenshen/p/6500627.html
Copyright © 2011-2022 走看看