覆盖函数,看到类中定义了bool

时间:2012-10-31 07:01:44

标签: python html-parsing global

我正在尝试解析python中的一些html页面。当我到达某个标签时,我想开始打印所有数据。到目前为止,我想出了这个:

class MyHTMLParser(HTMLParser):
    start = False;
    counter = 0;
    def handle_starttag(self,tag,attrs):
        if(tag == 'TBODY'):
            start = True;
            counter +=1
            #if counter == 1
    def handle_data(self,data):
        if (start == True): # this is the error line
            print data

问题是有一个错误,说它不知道什么是开始。我知道我可以使用全局,但这不会强迫我在整个类之外定义变量吗?

编辑: 将start更改为self.start可以解决问题,但有没有办法在 init 中定义它而不会弄乱HTMLParser init?

3 个答案:

答案 0 :(得分:2)

class MyHTMLParser(HTMLParser):
    start = False;
    counter = 0;
    ...

这不符合你的想法!

在Java,C#或类似语言中,类似代码所做的是声明被称为MyHTMLParser的对象类都具有属性start,其初始值为Falsecounter,初始值为0

在Python中,类也是对象。它们有自己的属性,就像其他所有对象一样。所以上面在Python中做的是创建一个名为MyHTMLParser的类对象,其中属性start设置为False,属性counter设置为0 1

要记住的另一件事是没有办法来分配像start = True这样的裸名称在对象上设置属性。它总是设置一个名为start 2

的变量

因此,您的类不包含任何在MyHTMLParser个实例上设置任何属性的代码;类主体中的代码是在类对象本身上设置属性,handle_starttag中的代码设置局部变量,然后当它们超出范围时被丢弃。

handle_data中的代码正在读取名为start的局部变量(您从未设置过),原因类似。在Python中,如果没有指定要查找的对象,就无法读取属性。裸start始终引用变量,在本地函数范围或某些外部范围内。您需要self.start才能阅读start对象的self属性。

请记住,定义方法的def块没有什么特别之处,它是一个像其他任何函数一样的函数。只有在该函数恰好存储在类对象的属性中时才能将该函数归类为方法。因此self参数的行为与任何其他参数相同,实际上与任何其他名称相同。它不必被命名为self(虽然这是一个明智的约定),并且它没有特殊权限,使得对裸名称的读取和写入寻找self的属性。

所以:

  1. 不要在类块中使用初始值定义属性;这是由所有类的实例共享的值,而不是每个实例的属性。只有在引用特定实例后,才能初始化实例属性;最常见的是,这是在__init__方法中完成的,只要对象存在就会调用该方法。

  2. 必须指定要在哪个对象中读取或写入属性。这在每个上下文中应用始终。特别是,您通常会将方法中的属性称为self.attribute

  3. 应用它(并消除Python中不需要的分号):

    class MyHTMLParser(HTMLParser):
        def __init__(self):
            start = False
            counter = 0
    
        def handle_starttag(self, tag, attrs):
            if(tag == 'TBODY'):
                self.start = True
                self.counter += 1
    
        def handle_data(self, data):
            if (self.start == True):
                print data
    

    1 方法handle_starttaghandle_data也只不过是恰好是用作类的对象属性的函数。

    2 通常是一个局部变量;如果您已将start声明为globalnonlocal,那么它可能是外部变量。但它肯定不是你碰巧在附近的某个对象的属性,即使该另一个对象绑定到名称self

答案 1 :(得分:1)

使用self关键字

class MyHTMLParser(HTMLParser):
    def __init__(self):
        self.start = False;
        self.counter = 0;
    def handle_starttag(self,tag,attrs):
        if(tag == 'TBODY'):
            self.start = True;
            self.counter +=1
            #if counter == 1
    def handle_data(self,data):
        if (self.start == True): # this is the error line
            print data

答案 2 :(得分:0)

注意,您不需要在每行的末尾添加分号;。您可以将其用作分隔符,以便在必要时将多个语句放在同一行上。见Why is semicolon allowed in this python snippet?