Python 为什么在这个方法中不使用“self”?
我的印象是Python类中的方法总是需要Python 为什么在这个方法中不使用“self”?,python,python-3.x,typeerror,self,Python,Python 3.x,Typeerror,Self,我的印象是Python类中的方法总是需要self参数(我知道它实际上不必是self,只需要一些关键字)。但是,我编写的这个类不需要它: import ZipFile import os class Zipper: def make_archive(dir_to_zip): zf = zipfile.ZipFile(dir_to_zip + '.zip', 'w') for filename in files: zf.write(os
self
参数(我知道它实际上不必是self
,只需要一些关键字)。但是,我编写的这个类不需要它:
import ZipFile
import os
class Zipper:
def make_archive(dir_to_zip):
zf = zipfile.ZipFile(dir_to_zip + '.zip', 'w')
for filename in files:
zf.write(os.path.join(dirname, filename))
zf.close()
看到了吗?无self
。当我在make_archive
中包含一个self
参数时,我会得到一个TypeError:make_archive()缺少一个位置参数的错误。在我寻找原因的过程中,我从文档中复制并尝试运行一个类似的程序:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
print(MyClass.f()) # I added this statement to have a call line
我也犯了同样的错误
TypeError: f() missing 1 required positional argument: 'self'
在包含Zipper()
类的同一个模块中,我有多个类都使用self
。我不理解这里的理论,这使得我很难知道什么时候该做什么,特别是因为直接从docs()复制的程序在运行时失败了。我在DebianLinux上使用Python3.5和3.4。我能想到的唯一一件事是它是一个静态方法(上面写的Zipper.make_archive()
如果在make_archive
方法上面包含@staticmethod
),那么它可以正常工作,但是我找不到一个好的解释来确定。您正试图将它用作静态方法。以你为例
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
a = MyClass()
a.f() # This should work.
调用MyClass.f()
假定f
对于MyClass
是静态的。您可以将其设置为静态,如下所示:
class MyClass:
@staticmethod
def f(): # No self here
return 'hello world'
MyClass.f()
您正试图将其用作静态方法。以你为例
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
a = MyClass()
a.f() # This should work.
调用MyClass.f()
假定f
对于MyClass
是静态的。您可以将其设置为静态,如下所示:
class MyClass:
@staticmethod
def f(): # No self here
return 'hello world'
MyClass.f()
self
的问题在于它是隐式添加的。也就是说,调用代码显示Myclass().f()
,但被调用方看到Myclass().f(self)
。它还意味着从Myclass
的某个实例调用该方法,该实例位于self
变量中。关键是,方法可能以某种方式使用和/或修改实例数据(否则,它们为什么会在该类中?),并且自动提供相关实例非常方便
如果您不需要实例数据,那么您应该使用@staticmethod
,如果它实际上更像一个函数而不是对象方法,或者@classmethod
,如果该方法是要继承的,并且可能由不同的类以不同的方式使用。请参阅@pankaj daga-answer,了解静态方法的一些介绍
通过import Foo
导入的函数也使用Foo.bar()
语法,而不是从Foo import bar
导入的,这也可能造成混淆。就你的目的而言,这是一件完全不同的事情。self
的事情是隐式添加的。也就是说,调用代码显示Myclass().f()
,但被调用方看到Myclass().f(self)
。它还意味着从Myclass
的某个实例调用该方法,该实例位于self
变量中。关键是,方法可能以某种方式使用和/或修改实例数据(否则,它们为什么会在该类中?),并且自动提供相关实例非常方便
如果您不需要实例数据,那么您应该使用@staticmethod
,如果它实际上更像一个函数而不是对象方法,或者@classmethod
,如果该方法是要继承的,并且可能由不同的类以不同的方式使用。请参阅@pankaj daga-answer,了解静态方法的一些介绍
通过
import Foo
导入的函数也使用Foo.bar()
语法,而不是从Foo import bar导入的,这也可能造成混淆。就你而言,这是一件完全不同的事情。“我不理解这里的理论,这使得很难知道什么时候该做什么,特别是因为直接从文档复制的程序(这是文档页面)在我运行时失败了。”失败的部分不是你从文档复制的部分。该部分的下一个代码片段演示了类的“实例化”。接下来的几节将介绍实例的属性(包括方法)等。您需要阅读和理解代码片段之间的文本,而不仅仅是测试代码。此外,您的术语到处都是。如果您试图从文档中自学该语言,请注意,这可能是一段颠簸的旅程。无论如何,在这方面要更加小心;编程要求精确。StackOverflow并不是一个帮助人们学习语言基础知识的地方,尤其不是“如何编程”;这是为了解决工作中出现的特定技术问题。我理解StackOverflow是为了“解决工作中出现的特定技术问题”。我个人认为这是在我的工作中出现的一个具体的技术问题,考虑到我问了一个具体的问题:“为什么这不需要论证<代码>自我/代码>?”当我遇到这个问题时,我正在研究一个个人项目。在提出这个问题之前,我做了大量的研究,这是必须的。我不知道你对我的术语是什么意思,但谢谢你的警告。如果你有更好的地方在凌晨2:30问编程问题,我很乐意把它放在这里。“我不理解这里的理论,这使得很难知道什么时候该做什么,特别是因为直接从文档复制的程序(这是文档页面)在我运行时失败了。”失败的部分不是你从文档复制的部分。该部分的下一个代码片段演示了类的“实例化”。接下来的几节将介绍实例的属性(包括方法)等。您需要阅读和理解代码片段之间的文本,而不仅仅是测试代码。此外,您的术语到处都是。