html tool

2019年4月29日星期一

@staticmethod和@classmethod的作用与区别


问题:


       1.  @classmethod 的含义
       2.  PytestExperimentalApiWarning.simple("testdir.copy_example") 这里为什么只有1个参数,声明定义中不是两个吗?


pytest 的testing 阅读中发现如下的使用
源码:

0) from _pytest.warning_types import PYTESTER_COPY_EXAMPL
在 /src/_pytest/warning_types.py中
 60 PYTESTER_COPY_EXAMPLE = PytestExperimentalApiWarning.simple("testdir.copy_example")

而这个  PytestExperimentalApiWarning.simple 定义在src/_pytest/warning_types.py,如下:
 28 class PytestExperimentalApiWarning(PytestWarning, FutureWarning):
 29     """
 30     Bases: :class:`pytest.PytestWarning`, :class:`FutureWarning`.
 31       
 32     Warning category used to denote experiments in pytest. Use sparingly as the API might     change or even be
 33     removed completely in future version
 34     """
 35       
 36     @classmethod                      
 37     def simple(cls, apiname):         
 38         return cls(                   
 39             "{apiname} is an experimental api that may change over time".format(
 40                 apiname=apiname       
 41             )                         
 42         )                             
 43                                       
 44              


解释:

参考:
https://blog.csdn.net/handsomekang/article/details/9615239
https://blog.csdn.net/nyist327/article/details/47679771

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

而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

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

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

如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。


一是通过def定义的 普通的一般的,需要至少传递一个参数,一般用self,这样的方法必须通过一个类的实例去访问,类似于c++中通过对象去访问;

二是在def前面加上@classmethod,这种类方法的一个特点就是可以通过类名去调用,但是也必须传递一个参数,一般用cls表示class,表示可以通过类直接调用;

三是在def前面加上@staticmethod,这种类方法是静态的类方法,类似于c++的静态函数,他的一个特点是参数可以为空,同样支持类名和对象两种调用方式;

没有评论:

发表评论