1

我正在尝试掌握 python 2.6 的窍门,这是我对编程语言的介绍。我正在关注 Learn Python the Hard Way,我一定错过了一些东西。我有一组想要组合成一个类的函数。这些函数都包含在这里。我试图将它们组合成一个名为“Parsers”的类。此代码包含在此处

函数本身在类之外工作。我正在尝试像这样从类中调用函数:

导入模块:

>>> from ex48 import parser2

分配班级:

>>> parser_class = parser2.Parsers()

调用一个函数:

>>> parser_class.parse_subject(word_list, ('noun', 'player'))

我得到以下信息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ex48/parser2.py", line 60, in parse_subject
    verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined

不知道为什么它告诉我。有人可以指出我正确的方向吗?

4

3 回答 3

3

你对你的代码在做什么感到困惑。

这不会分配一个类,它会创建一个实例,并将该实例分配给一个变量:

parser_class = parser2.Parsers()

这会在该实例上调用一个方法:

parser_class.parse_subject(word_list, ('noun', 'player'))

下面告诉你没有全局函数(或者实际上是任何类型的变量)parse_verb

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ex48/parser2.py", line 60, in parse_subject
    verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined

我希望您想将其更改为verb = self.parse_verb(word_list),这将调用parse_verb同一对象 ( self) 的方法。

于 2012-10-31T17:12:18.657 回答
2

这里有两个问题,一个是机械的,一个是概念的。我先处理后者。

一个类的全部意义在于它的实例代表了你的世界模型中的某种对象。例如,“句子”是一个对象,因此有一个名为 的类是有意义的Sentence,但“解析器”不是一个对象,因此Parsers可能会成为一个混淆类。从不那么抽象的角度来看,一个类通常具有某种状态,封装在其方法工作的数据成员中。

您在这里真正拥有的是一个解析器函数,它返回一个Sentence对象(或引发 a ParserError)。这个函数可以是 的一个方法Sentence,也可以是一个自由函数;如果您的模型中有任何理由存在这样的对象,它也可能是Parser类的方法,但似乎没有。

如果您只是想封装所有这些辅助函数,以便它们不会乱扔全局命名空间(这本身就是一个好主意),那么您不需要滥用类来做到这一点。只需将它们制作成内部的本地函数parse_sentence,或者将它们放在一个名为parsers.

现在,关于机械问题:如果你在一个类中有一个方法,你通常只能通过点语法调用它:someObject.methodName(params). 当一个方法调用同一对象的另一个方法时,您可以使用特殊self参数(您已正确地将其列为每个方法的第一个参数)来执行此操作。所以:

verb = self.parse_verb(word_list)
obj = self.parse_object(word_list)

... 以此类推,适用于您的示例中的所有其他方法调用。

并非每种语言都需要这样的显式self。例如,在 C++ 或相关语言(Java、C# 等)中,一个方法可以在不指定目标的情况下调用另一个方法,并且隐式假定目标是this(C++ 等价于self)。

于 2012-10-31T17:31:56.580 回答
1

看起来您正在使用 python 交互式会话。

如果您parser2.py在导入后进行了任何更改parser2,那么您必须

reload(parser2)

使交互式解释器知道这些更改。

于 2012-10-31T17:08:57.400 回答