0

我正在尝试在 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 是什么。我知道我可以使用全局变量,但这不会强迫我在整个类之外定义变量吗?

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

4

3 回答 3

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

这并不像你认为的那样!

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

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

要记住的另一件事是,没有任何方法可以对裸名称进行分配,例如start = True在对象上设置属性。它总是设置一个名为 的变量start2

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

出于类似的原因,您的代码正在从名为(您从未设置过)handle_data的局部变量中读取。start在 Python 中,如果不指定要在哪个对象中查找属性,就无法读取属性。barestart总是指代变量,无论是在本地函数范围内还是在某些外部范围内。您需要self.start读取对象的start属性self

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

所以:

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

  2. 必须指定要在哪个对象中读取或写入属性。这始终适用于任何情况。特别是,您通常将方法内的属性称为self.attribute.

应用它(并消除在 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通常是局部变量;如果您已声明startglobalnonlocal则它可能是外部变量。但它绝对不是您碰巧在附近的某个对象的属性,即使该其他对象绑定到 name self

于 2012-10-31T07:39:02.000 回答
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
于 2012-10-31T07:07:31.927 回答
0

请注意,您不需要;在每行的末尾添加分号。如有必要,您可以将其用作分隔符以将多个语句放在同一行上。请参阅为什么在这个 python 片段中允许使用分号?

于 2012-10-31T07:20:08.710 回答