我正试图了解python 2.6,这是我对编程语言的介绍。我正在按照艰难的方式学习Python,我一定错过了一些东西。我有一组函数要组合成一个类。这些函数包含here。我试图将这些组合成一个名为“Parsers”的类。此代码包含here。
函数本身在类之外工作。我试图像这样调用类中的函数:
导入模块:
>>> 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
不确定为什么它会告诉我。有人能指出我正确的方向吗?
答案 0 :(得分: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
的{{1}}方法。
答案 1 :(得分:2)
这里有两个问题,一个是机械的,一个是概念的。我先讨论后者。
一个类的重点是它的实例代表了你的世界模型中的某种对象。例如,“句子”是一个对象,因此有一个名为Sentence
的类是有意义的,但“解析器”不是一个对象,所以Parsers
可能会是一个混淆的类。不那么抽象地看待事物,类通常具有某种状态,封装在其方法所依据的数据成员中。
你真正拥有的是一个解析器函数,它返回一个Sentence
对象(或引发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
})。
答案 2 :(得分:1)
看起来你正在通过python交互式会话工作。
如果您在导入parser2.py
后对parser2
进行了任何更改,那么您必须
reload(parser2)
使交互式解释器知道这些更改。