search

Home  >  Q&A  >  body text

python 类方法的使用场景

python的类方法的定义和使用都了解, 问题是什么情况下会使用python类方法,而不是普通方法或静态方法?

大家讲道理大家讲道理2813 days ago964

reply all(2)I'll reply

  • 黄舟

    黄舟2017-04-18 09:43:46

    The example I can think of is that class methods are often used as a replacement for constructors (__init__).

    Here is a simple example:

    class Calculator:
    
        def __init__(self, *numbers):
            self.numbers = numbers
    
        def sum(self):
            return sum(self.numbers)
    
        def avg(self):
            return sum(self.numbers)/len(self.numbers)
    
    if __name__ == '__main__':
        c = Calculator(1,2,3,4,5)
        print(c.sum())
        print(c.avg())    

    This is a completely useless calculator class, but let’s not worry about it so much. The constructor of this class uses star expression to complete the function of receiving any number of positional arguments. Let’s consider a situation. If a user wants How to construct this class given a sequence (List or Tuple)?

    In fact, just use star expression:

        numbers = [6,7,8,9,10]
        c2 = Calculator(*numbers)
        print(c2.sum())
        print(c2.avg())

    But classmethod is another option at this time:

    class Calculator:
    
        def __init__(self, *numbers):
            self.numbers = numbers
    
        def sum(self):
            return sum(self.numbers)
    
        def avg(self):
            return sum(self.numbers)/len(self.numbers)
    
        @classmethod
        def fromseq(cls, seq):
            return cls(*seq)
    
    if __name__ == '__main__':
        numbers = [6,7,8,9,10]
        c3 = Calculator.fromseq(numbers)
        print(c3.sum())
        print(c3.avg())

    We can easily use classmethod to implement constructor replacements. The key reason is that the first parameter of classmethod receives a class object. This allows us to process the arguments passed in by classmethod to become acceptable in standard constructors. Enter, reuse the class object to create the object and return.

    If this matter is handed over to the instance method, there will be one more conversion method using type(self). Using staticmethod requires hard-coding the class name in the method, which is not so appropriate:

    class Calculator:
        ...(略)...
        
        @classmethod
        def fromseq(cls, seq):
            return cls(*seq)
        
        def fromseq2(self, seq):
            return type(self)(*seq) # 多一個步驟
            
        @staticmethod
        def fromseq3(seq):
            return Calculator(*seq) # 哪一天這個類改名字了這裡也要改...

    If you want to know more about instance method, classmethod and staticmethod, you can refer to:

    • Under what circumstances is Python’s staticmethod used

    • The definitive guide on how to use static, class or abstract methods in Python


    Questions I answered: Python-QA

    reply
    0
  • 阿神

    阿神2017-04-18 09:43:46

    Wait a minute and write an example~


    python3

    class 类方法演示(object):
    
        类变量 = '哈哈'
    
        def __init__(实例):
            实例.实例变量 = '实例值'
    
        def 测试1(实例): #实例方法
            print('测试1')
            print(实例)
    
        @classmethod #类方法
        def 测试2(此类): # 此类 就是 类方法演示 自身
            print(此类)
            print('测试2')
            print(类方法演示.类变量)
            print('----------------')
    
        @staticmethod #静态方法
        def 测试3(): # 这里可以不传递参数。
            print(类方法演示.类变量)
            print('测试3')
    
    if __name__ == '__main__':
        对象 = 类方法演示()
        对象.测试1()
        对象.测试2()
        对象.测试3()
        类方法演示.测试3()
    

    类方法静态方法皆可以访问类变量,但不能访问实例变量
    静态变量,python里好像只能通过闭包来实现静态变量.

    reply
    0
  • Cancelreply