Python——为什么实例方法是;“违约”;类中的方法?
python类中的函数可以是实例方法、类方法或静态方法 前者的特点是将Python——为什么实例方法是;“违约”;类中的方法?,python,class,oop,methods,Python,Class,Oop,Methods,python类中的函数可以是实例方法、类方法或静态方法 前者的特点是将self作为其第一个(隐式)参数,直接作用于类的实例,并且不要求将任何装饰器视为此类 但是,另外两个方法在方法名称之前需要decorators@classmethod和@staticmethod——这就是为什么我将实例方法称为“默认”方法,即不需要包装的方法 我的问题是:假设我在一个类中,为了便于阅读,我将我的计算分解为几个函数。这些方法中只有一个需要访问self.something变量,我在实例方面共享这些变量,但大多数其
self
作为其第一个(隐式)参数,直接作用于类的实例,并且不要求将任何装饰器视为此类
但是,另外两个方法在方法名称之前需要decorators@classmethod
和@staticmethod
——这就是为什么我将实例方法称为“默认”方法,即不需要包装的方法
我的问题是:
假设我在一个类中,为了便于阅读,我将我的计算分解为几个函数。这些方法中只有一个需要访问self.something变量,我在实例方面共享这些变量,但大多数其他方法不需要知道它们所属的类,它们只是用于“内务管理” 应该使这些函数(那些不需要任何
自身知识的函数)都@staticmethod
<这样做需要一个装饰师,因此需要额外的步骤
每个方法都只是一个实例方法会更容易(不需要使用分解器的额外步骤),因此继承了很多潜力,但也缩小了它,因为在所讨论的函数范围内不需要它
为什么实例方法是“默认值”
为什么不在默认情况下让每个方法都是静态方法,并为其提供与使用包装器作为实例方法相关的额外功能?默认为实例方法的原因是,这通常是您在进行面向对象编程时想要的。我想不出有哪一种语言声称支持OOP,并且除了实例方法之外,其他方法都是默认的。类是“具有行为的数据”的模板,因此默认情况下是生成为类的每个实例化提供行为的方法。如果您只需要一组函数,那么您可以在模块的顶层定义它们,并保存不必要的类
一般来说,@staticmethod
的意思是“我知道这不是类或其实例的行为,但它有助于实现真正的行为,在类之外也不是很有用,所以我将在类内部命名它。”如果这些功能在类之外有用,您只需将其作为一个简单的顶级函数,而不是将其放在类中。适当时使用@staticmethod
是有利的;调用比实例方法快一点,因此,如果不需要实例,@staticmethod
将稍微加快代码的速度(注意:在3.7+中可能不是这样,其中可能会加快实例/类方法的速度)
@classmethod
基本上有两个用例:
(主要)以子类友好的方式定义备用构造函数(它接收的cls
是实际的子类,如果适用,而不仅仅是它在其中定义的类)
(大部分是不必要的)作为@staticmethod
的替代方法,当该方法需要调用其他静态方法时,您不必反复按名称引用该类
关键是,@staticmethod
主要用于您选择退出OOP时,而@classmethod
则用于特定的用例;实例方法更有用,所以它们是默认的。除此之外,作为历史记录,静态方法和类方法是后来引入的,因此如果将它们设为默认值,将破坏所有现有的Python代码,而不会带来真正的好处
使用@staticmethod
覆盖实例方法并忽略self
(当不需要self
时)的主要原因是,在类本身上调用时,它将继续工作,而不仅仅是在类的实例上;如果您试图调用MyClass.NotRealyStatic()
,它会因为缺少自身而死掉,而MyClass.ActualyStatic()
可以工作。默认为实例方法的原因是,这通常是您在进行面向对象编程时想要的。我想不出有哪一种语言声称支持OOP,并且除了实例方法之外,其他方法都是默认的。类是“具有行为的数据”的模板,因此默认情况下是生成为类的每个实例化提供行为的方法。如果您只需要一组函数,那么您可以在模块的顶层定义它们,并保存不必要的类
一般来说,@staticmethod
的意思是“我知道这不是类或其实例的行为,但它有助于实现真正的行为,在类之外也不是很有用,所以我将在类内部命名它。”如果这些功能在类之外有用,您只需将其作为一个简单的顶级函数,而不是将其放在类中。适当时使用@staticmethod
是有利的;调用比实例方法快一点,因此,如果不需要实例,@staticmethod
将稍微加快代码的速度(注意:在3.7+中可能不是这样,其中可能会加快实例/类方法的速度)
@classmethod
基本上有两个用例:
(主要)以子类友好的方式定义备用构造函数(它接收的cls
是实际的子类,如果适用,而不仅仅是它在其中定义的类)
(大部分是不必要的)作为@staticmethod
的替代方法,当该方法需要调用其他静态方法时,您不必反复按名称引用该类
关键是,@staticmethod
主要用于您选择退出OOP时,而@classmethod
则用于特定的用例;实例方法更有用,所以它们是默认的。除此之外,作为一名历史学家