Python,__ init__和自我混淆

时间:2009-03-23 18:20:45

标签: python self init

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

>>> 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不是吗?为什么这么重要!

我只想要一个基本的解释,所以我可以忘记这一点,谢谢。

5 个答案:

答案 0 :(得分: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类中拉出来并单独使用。它不是一个独立的功能。它是在里面定义的,并且因为类中的位置而具有一定的期望。

答案 1 :(得分: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()

答案 2 :(得分:1)

看起来你对类和面向对象编程有点困惑。对于来自其他编程语言的人来说,'self'是python中的陷阱之一。 IMO官方教程不能很好地处理它。 This tutorial似乎相当不错。

如果你曾经学过java,那么python中的self与java中的this非常相似。区别在于python要求您将self列为类定义中每个函数的第一个参数。

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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