Python 为什么在这个方法中不使用“self”?

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

我的印象是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.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问编程问题,我很乐意把它放在这里。“我不理解这里的理论,这使得很难知道什么时候该做什么,特别是因为直接从文档复制的程序(这是文档页面)在我运行时失败了。”失败的部分不是你从文档复制的部分。该部分的下一个代码片段演示了类的“实例化”。接下来的几节将介绍实例的属性(包括方法)等。您需要阅读和理解代码片段之间的文本,而不仅仅是测试代码。此外,您的术语到处都是。