python 类方法 静态方法 实例方法

1 类方法

@classmethod
会把一个方法封装成类方法。

一个类方法把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。请用以下习惯来声明类方法:

class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...

@classmethod 这样的形式称为函数的 decorator – 详情参阅 函数定义。
( C . f ( ) ) ( C ( ) . f ( ) ) \color{red}{类方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。}
其所属类以外的类实例会被忽略。 如果类方法在其所属类的派生类上调用,则该派生类对象会被作为隐含的第一个参数被传入。
类方法与 C++ 或 Java 中的静态方法不同。 如果你需要后者,请参阅 staticmethod()。

2 静态方法

@staticmethod
将方法转换为静态方法。

\color{red} 静态方法不会接收隐式的第一个参数。 要声明一个静态方法,请使用此语法

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@staticmethod 这样的形式称为函数的 decorator – 详情参阅 函数定义。

( C . f ( ) ) ( C ( ) . f ( ) ) \color{red} 静态方法的调用可以在类上进行 (例如 C.f()) 也可以在实例上进行 (例如 C().f())。

Python中的静态方法与Java或C ++中的静态方法类似。另请参阅 classmethod() ,用于创建备用类构造函数的变体。

像所有装饰器一样,也可以像常规函数一样调用 staticmethod ,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。对于这些情况,请使用此语法:

class C:
    builtin_open = staticmethod(open)

想了解更多有关静态方法的信息,请参阅 标准类型层级结构 。

3 区别

  • 构造不同:类方法需要把类自己作为第一个实参cls,静态方法不会接收隐式的第一个参数,实例方法把实例自己作为第一个实参self;
  • 实例方法需要创造实例后才能调用,而其它两种可以直接依靠类进行调用,创造实例后依旧可以使用类方法和静态方法;
  • java类的构造函数可以重载,python 类方法用在模拟java定义多个构造函数的情况;
  • python的静态方法用途和java一样,旨在类和实例都能调用,创建实例后,不会另行创建一个新的静态方法,用的是父类的;
  • 静态方法应用场景 :如果在方法中不需要访问任何实例方法和属性,纯粹地通过传入参数并返回数据的功能性方法,那么它就适合用静态方法来定义,它节省了实例化对象的开销成本,往往这种方法放在类外面的模块层作为一个函数存在也是没问题的,而放在类中,仅为这个类服务。
  • 类方法使用场景:1、作为工厂方法创建实例对象,例如内置模块 datetime.date 类中就有大量使用类方法作为工厂方法,以此来创建date对象。2、如果希望在方法裡面调用静态类,那么把方法定义成类方法是合适的,因为要是定义成静态方法,那么你就要显示地引用类A,这对继承来说可不是一件好事情。
# coding:utf-8
class Foo(object):
    """类三种方法语法形式"""
    x,y = 10,14
    def instance_method(self):
        pass
    @staticmethod
    def static_method_averag(*mixes):
        return sum(mixes) / len(mixes)

    @classmethod
    def class_method(cls):
        return cls.static_method_averag(cls.x,cls.y)

foo = Foo()
# 调用关系
# foo.instance_method()
# foo.static_method_averag(1,2,3)
# foo.class_method()
# print('----------------')
# Foo.static_method_averag(1,2,3)
# Foo.class_method()
# print('----------------')

# 内存关系
print(Foo.static_method_averag is  foo.static_method_averag)  #静态方法不会动
print(Foo.class_method is  foo.class_method)
print(Foo.instance_method is  foo.instance_method)  #实例化后 实例绑定这个方法



参考:
https://zhuanlan.zhihu.com/p/28010894
https://docs.python.org/zh-cn/3/index.html

发布了105 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/x1131230123/article/details/104475923