Python,__ init__和自我混淆

Python, __init__ and self confusion

好吧,当我遇到这个问题的时候,我正在看一些资料来源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> 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
...

所以,我决定测试一下。

1
 >>> __parse("blah.mp3")

我收到这个错误:

1
2
3
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):打印b与def x(self,b):self相同。b=b打印self。b不是吗?为什么这么重要?

我只想得到一个基本的解释,所以我可以把它从我的脑海里拿出来,谢谢。


def __parse在一些类定义中。

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

看看这两个例子:

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

1
2
3
4
5
6
class Adder( object ):
    def __init__( self ):
        self.grand_total = 0
    def add( self, a, b ):
        self.grand_total += a+b
        return a+b

笔记。

  • 该函数不使用self

  • class方法确实使用了self。一般来说,所有实例方法都将使用self,除非它们有特定的装饰器,如@classmethod,否则会使用其他的装饰器。

  • 这个函数不依赖于其他任何东西。

  • class方法依赖于类EDOCX1的一个实例(5)调用;此外,它还依赖于类EDOCX1的那个实例(5)已正确初始化。在这种情况下,初始化函数(__init__确保Adder的每个实例始终有一个名为grand_total的实例变量,该实例变量的初始值为0

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class C(object):
      def __init__(self):
        self.foo = 'bar'

    def __output(self):
      print self.foo

    C.output = __output
    c = C()
    c.output()


    看起来你对类和面向对象编程有点困惑。对于来自其他编程语言的人来说,"self"是Python中的一个亮点。在我看来,官方的教程处理得不太好。本教程似乎相当不错。

    如果你曾经学习过Java,那么在Python中,EDOCX1 1是非常类似于Java中的EDCOX1×15的。区别在于,python要求您将self列为类定义中每个函数的第一个参数。

    如果Python是您的第一种编程语言(或第一种面向对象的语言),您可以将其记为一个简单的经验法则:如果您定义的函数是类的一部分,则需要将self作为第一个参数。如果定义的函数不是类的一部分,则不应在参数中包含self。如果不进行一些(或者可能大量)额外的编码,就无法获取类函数并使其独立。最后,在调用函数时,不要将self作为参数。

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


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


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