为什么在这种方法中没有使用`self`?

时间:2016-10-01 07:10:45

标签: 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.path.join(dirname, filename))
        zf.close()

请参阅?没有self。当我向self添加make_archive参数时,出现TypeError: make_archive() missing one positional argument错误。在我的搜索中找出为什么会发生这种情况,我实际上已经复制并试图从文档中运行类似的程序:

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。我不理解这里的理论,这使得很难知道何时做什么,特别是因为直接从文档(this is the docs page)复制的程序在运行时失败了。我在Debian Linux上使用Python 3.5和3.4。我唯一能想到的是它是一个静态方法(如果你在Zipper.make_archive()方法之上包含@staticmethod,上面写的make_archive工作正常),但我无法找到一个好的解释。

2 个答案:

答案 0 :(得分:0)

您正尝试将其用作静态方法。在你的例子中;

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
       return 'hello world'

a = MyClass()
a.f()  # This should work.

调用MyClass.f()假定fMyClass是静态的。您可以将其设为静态:

class MyClass:
    @staticmethod
    def f():  # No self here
       return 'hello world'

MyClass.f()

答案 1 :(得分:0)

self的内容是它隐式添加 。也就是说,调用代码显示Myclass().f(),但被调用者看到Myclass().f(self)。它还意味着从Myclass的某个实例调用该方法,该实例放在self变量中。关键是方法可能以某种方式使用和/或修改实例数据(否则它们为什么会在该类中?)并且自动提供有问题的实例是很方便的。

如果你不需要实例数据,你应该使用@staticmethod,如果它实际上更像是一个函数而不是对象方法,或者@classmethod如果该方法是为了继承而且可能以不同的方式使用由不同的班级。请参阅@ pankaj-daga答案,了解staticmethods的一些介绍。

Foo.bar()语法也被import Foo而不是from Foo import bar导入的函数使用,这也是混淆的可能来源。为了您的目的,这是完全不同的事情。