zoukankan      html  css  js  c++  java
  • Python @classmethod

    @classmethod:

    定义操作类,而不是操作实例的方法。classmethod改变了调用方法的方式,因此类方法的第一个参数是类本身,而不是实例。@classmethod最常见的用途是定义备选构造方法。

    1.定义方式

    Python中3种方式定义类方法, 常规方式, @classmethod修饰方式, @staticmethod修饰方式
    • 普通的self类方法foo()需要通过self参数隐式的传递当前类对象的实例

    • @classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象

    • @staticmethod修饰的方法定义与普通函数是一样的。

    self和cls的区别不是强制的,只是PEP8中一种编程风格,self通常用作实例方法的第一参数,cls通常用作类方法的第一参数。即通常用self来传递当前类对象的实例,cls传递当前类对象。

    2. @classmethod 特点

    • 声明一个类方法
    • 第一个参数必须是 cls, 它可以访问类的属性
    • 类的方法只能访问类的属性,不能访问实例属性
    • 类的方法可以通过 ClassName.MethodName() 访问也可以通过实例来访问。
    • 它可以返回一个类的实例

    例子:

    class Student:
        name = 'unknown' # class attribute
        def __init__(self):
            self.age = 20  # instance attribute
    
        @classmethod
        def tostring(cls):
            print('Student Class Attributes: name=',cls.name)
    

    类方法访问实例属性时,会报错

    class Student:
        name = 'unknown' # class attribute
        def __init__(self):
            self.age = 20  # instance attribute
    
        @classmethod
        def tostring(cls):
            print('Student Class Attributes: name=',cls.name,', age=', cls.age)
    
    >>> Student.tostring()
    Traceback (most recent call last):
      File "<pyshell#22>", line 1, in <module>
        Student.tostring()
      File "<pyshell#21>", line 7, in display
        print('Student Class Attributes: name=',cls.name,', age=', cls.age)
    AttributeError: type object 'Student' has no attribute 'age'
    

    例子

    from datetime import date
    
    # random Person
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @staticmethod
        def fromFathersAge(name, fatherAge, fatherPersonAgeDiff):
            return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)
    
        @classmethod
        def fromBirthYear(cls, name, birthYear):
            return cls(name, date.today().year - birthYear)
    
        def display(self):
            print(self.name + "'s age is: " + str(self.age))
    
    class Man(Person):
        sex = 'Male'
    
    man = Man.fromBirthYear('John', 1985)
    print(isinstance(man, Man))
    
    man1 = Man.fromFathersAge('John', 1965, 20)
    print(isinstance(man1, Man))
    

    3. @classmethod 和 @staticmethod

    @classmethod @staticmethod
    声明一个类的方法 声明一个静态方法
    可以访问类的属性,不可以访问实例属性 既不可以访问类属性,也不可以访问实例属性
    可以使用 ClassName.MethodName() 调用或者 object.MethodName().调用 可以使用 ClassName.MethodName() 调用后者object.MethodName().调用
    可以声明一个类的工厂方法,返回一个实例 不可以返回一个实例

    参考:

    https://www.programiz.com/python-programming/methods/built-in/classmethod
    https://www.tutorialsteacher.com/python/classmethod-decorator

    不要小瞧女程序员
  • 相关阅读:
    LeetCode 230. Kth Smallest Element in a BST
    LeetCode 114. Flatten Binary Tree to Linked List
    LeetCode 222. Count Complete Tree Nodes
    LeetCode 129. Sum Root to Leaf Numbers
    LeetCode 113. Path Sum II
    LeetCode 257. Binary Tree Paths
    Java Convert String & Int
    Java Annotations
    LeetCode 236. Lowest Common Ancestor of a Binary Tree
    LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/shix0909/p/15037612.html
Copyright © 2011-2022 走看看