我应该在这里使用一个类:使用lxml读取XML文件

时间:2010-06-15 12:25:03

标签: python design-patterns

这个问题是我之前提出的passing around an ElementTree.

问题的继续问题

我只需要阅读XML文件并解决这个问题,我决定创建一个全局的ElementTree,然后在需要的地方解析它。

我的问题是:

这是可接受的做法吗?我听说global变量很糟糕。如果我没有global,我会被建议制作一个class。但我真的需要创建一个class吗?从这种方法中我将获得什么好处。请注意,每次运行我只会处理一个 ElementTree实例,操作是只读的。如果我不使用class,我如何以及在何处声明ElementTree以使其全局可用? (请注意,我将导入此模块)

请回答这个问题,因为我是开发的初学者,在这个阶段我无法弄清楚是使用课程还是仅仅采用功能风格编程方法。

3 个答案:

答案 0 :(得分:0)

务实地说,您的代码是否会增长?尽管人们预示着OOP是正确的方式,但我发现有时候衡量成本会更好:每当你重构一段代码时都会受益。如果您希望增加这一点,那么OOP是一个更好的选择,因为您可以扩展和自定义任何未来的用例,同时节省您在代码维护中浪费的不必要时间。否则,如果没有损坏,请不要修理它,恕我直言。

答案 1 :(得分:0)

当我屈服于给出一个模块的诱惑时,我通常会后悔,例如, load_file()方法设置一个全局模块的其他函数可以用来查找他们应该谈论的文件。例如,它使测试变得更加困难,一旦我需要两个XML文件就会出现问题。另外,每个函数都需要检查文件是否存在,如果不存在则给出错误。

如果我想要功能,我只需要让每个函数都将XML文件作为参数。

如果我想要面向对象,我将有一个 MyXMLFile 类,其方法可以只查看 self.xmlfile 或其他。

当只有一个单独的东西(如文件)被传递时,这两种方法或多或少是等价的;但是当“状态”中的事物数量大于少数时,我发现类更简单,因为我可以将所有这些事情都粘在课堂上。

(我是否回答了你的问题?对于你想要的答案,我仍然很模糊。)

答案 2 :(得分:0)

全局变量的原因有几个。首先,它会让你习惯于声明全局变量这不是一个好习惯,尽管在某些情况下全局变量是有意义的 - 例如,PI。当您故意或意外地在本地重复使用该名称时,Globals也会产生问题。或者更糟糕的是,当你你在本地使用这个名字时,实际上你正在为全局变量分配一个新值。这个特殊的问题依赖于语言,python在不同的情况下处理它的方式不同。

class A:
   def __init__(self):
      self.name = 'hi'

x = 3
a = A()

def foo():
   a.name = 'Bedevere'
   x = 9

foo()
print x, a.name #outputs 3 Bedevere

创建类并传递类的好处是,您将获得一个已定义的常量行为,尤其是因为您应该调用类本身的类方法。

class Knights:
   def __init__(self, name='Bedevere'):
       self.name = name
   def knight(self):
       self.name = 'Sir ' + self.name
   def speak(self):
       print self.name + ":", "Run away!"

class FerociousRabbit:
   def __init__(self):
       self.death = "awaits you with sharp pointy teeth!"
   def speak(self):
       print "Squeeeeeeee!"

def cave(thing):
   thing.speak()
   if isinstance(thing, Knights):
       thing.knight()

def scene():
   k = Knights()
   k2 = Knights('Launcelot')
   b = FerociousRabbit()
   for i in (b, k, k2):
      cave(i)

这个例子说明了一些好的原则。首先,调用函数时python的强度 - FerociousRabbit和Knights是两个不同的类,但它们具有相同的函数speak()。在其他语言中,为了做这样的事情,他们至少必须拥有相同的基类。你想要这样做的原因是它允许你编写一个函数(洞穴),它可以在任何具有'speak()'方法的类上运行。您可以创建任何其他方法并将其传递给洞穴函数:

class Tim:
   def speak(self):
       print "Death awaits you with sharp pointy teeth!"

所以在你的情况下,当处理一个elementTree时,请说某些时候你需要开始解析一个apache日志。好吧,如果你正在做纯粹的功能性程序,你基本上就是软管。你可以修改和扩展你当前的程序,但是如果你编写好你的函数,你可以添加一个新的类,并且(技术上)一切都将是非常敏锐的。