3

好的,所以当我遇到这个时,我正在查看一些来源:

>>> def __parse(self, filename):
...         "parse ID3v1.0 tags from MP3 file"
...         self.clear()
...         try:
...             fsock = open(filename, "rb", 0)
...             try:
...                 fsock.seek(-128, 2)
...                 tagdata = fsock.read(128)
...             finally:
...                 fsock.close()
...             if tagdata[:3] == 'TAG':
...                 for tag, (start, end, parseFunc) in self.tagDataMap.items():
...                     self[tag] = parseFunc(tagdata[start:end])
...         except IOError:
...             pass
... 

所以,我决定测试一下。

 >>> __parse("blah.mp3")

而且,我收到了这个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __parse() takes exactly 2 arguments (1 given)

这不是我第一次遇到这种情况,我一直认为我应该将 self 包含在参数参数列表中,但我知道那是不对的。有人可以向我解释为什么我尝试使用的代码经常发生这种情况,我想这是由于我对这些术语的理解程度,我什至几乎不了解 init 或 self 做了什么,或者为什么它是相关的。def x(b): print b 和 def x(self, b): self.b = b print self.b 一样,不是吗?为什么这么重要!

我只是想要一个基本的解释,所以我可以摆脱这个想法,谢谢。

4

5 回答 5

8

def __parse某些类定义中。

您不能将方法 defs 从类定义中提取出来。方法函数定义是类的一部分。

看看这两个例子:

def add( a, b ):
    return a + b

class Adder( object ):
    def __init__( self ):
        self.grand_total = 0
    def add( self, a, b ):
        self.grand_total += a+b
        return a+b

笔记。

  1. 该功能不使用self.

  2. 类方法确实使用self. 通常,所有实例方法都将使用self,除非它们有特定的装饰器,如@classmethod另有说明。

  3. 该功能不依赖于其他任何东西。

  4. 类方法依赖于被类的实例调用Adder;此外,它取决于该类的实例Adder是否已正确初始化。在这种情况下,初始化函数 ( __init__) 确保 的每个实例Adder总是有一个名为的实例变量,并且该实例变量的grand_total初始值为0

  5. 你不能把add方法函数从Adder类中拉出来单独使用。它不是一个独立的功能。它是在类内定义的,并且由于类的位置而具有一定的期望。

于 2009-03-23T18:23:11.220 回答
2

函数/方法可以在类之外编写,然后用于 Python 中称为monkeypatching的技术:

class C(object):
  def __init__(self):
    self.foo = 'bar'

def __output(self):
  print self.foo

C.output = __output
c = C()
c.output()
于 2009-03-23T18:32:44.380 回答
1

看起来你对类和面向对象编程有点困惑。对于来自其他编程语言的人来说,“自我”是 python 的陷阱之一。IMO官方教程处理得不太好。 这个教程看起来很不错。

如果你曾经学过 java,那么selfin python 与 in java 非常相似this。不同之处在于,python 要求您列出self类定义中每个函数的第一个参数。

如果 python 是您的第一种编程语言(或您的第一种面向对象的语言),您可以将其记住为一个简单的经验法则:如果您要定义一个作为类的一部分的函数,则需要将其包含self为第一个争论。如果您要定义一个不属于类的函数,则不应包含self在参数中。如果不做一些(或者可能很多)额外的编码,你不能把一个类函数让它独立起来。最后,在调用self函数时永远不要包含作为参数。

这些规则也有例外,但现在不值得担心。

于 2009-03-23T22:05:32.543 回答
0

self 由类上的 instancemethod 包装器自动传入。这个函数没有被包装;它不是一个方法,它只是一个函数。如果没有附加到一个类,它甚至没有意义,因为它需要 self 参数。

于 2009-03-23T18:23:45.383 回答
0

顺便说一句,可以在 Python 中创建类的静态方法。最简单的方法是通过装饰器(例如@staticmethod)。我怀疑这种事情通常不是 Pythonic 解决方案。

于 2009-03-23T18:29:22.767 回答