| You are here: Inicio > Inmersión en Python > Scripts y flujos > Todo junto | << >> | ||||
Inmersión en PythonPython de novato a experto |
|||||
Ha cubierto mucho terreno. Volvamos atrás y comprobemos cómo se unen todas las piezas.
Para empezar, este es un script que toma argumentos desde la línea de órdenes usando el módulo getopt.
def main(argv): ... try: opts, args = getopt.getopt(argv, "hg:d", ["help", "grammar="]) except getopt.GetoptError: ... for opt, arg in opts: ...
Creamos una nueva instancia de la clase KantGenerator y le pasamos el fichero de gramática y una fuente que pueden haber sido especificados desde la línea de órdenes, o no.
k = KantGenerator(grammar, source)La instancia de KantGenerator carga automáticamente la gramática, que está en un fichero XML. Usamos la función openAnything modificada para abrir el fichero (que puede estar almacenado en un fichero local o en un servidor web remoto), luego usa las funciones de análisis que incorpora minidom para traducir el XML a un árbol de objetos de Python.
def _load(self, source):
sock = toolbox.openAnything(source)
xmldoc = minidom.parse(sock).documentElement
sock.close()Oh, y ya que estamos, aprovechamos nuestro conocimiento de la estructura del documentoXML para construir una pequeña caché de referencias que no son sino elementos del documento XML.
def loadGrammar(self, grammar):
for ref in self.grammar.getElementsByTagName("ref"):
self.refs[ref.attributes["id"].value] = ref Si especificamos algún material fuente en la línea de órdenes, lo usaremos; en caso contrario buscamos en la gramática la referencia de "nivel más alto" (que no está referenciada por ninguna otra) y la usamos como punto de partida.
def getDefaultSource(self):
xrefs = {}
for xref in self.grammar.getElementsByTagName("xref"):
xrefs[xref.attributes["id"].value] = 1
xrefs = xrefs.keys()
standaloneXrefs = [e for e in self.refs.keys() if e not in xrefs]
return '<xref id="%s"/>' % random.choice(standaloneXrefs)Ahora exploramos el material fuente. Este material también es XML y lo analizamos nodo por nodo. Para que el código sea desacoplado y de fácil mantenimiento, usamos manejadores diferentes por cada tipo de nodo.
def parse_Element(self, node):
handlerMethod = getattr(self, "do_%s" % node.tagName)
handlerMethod(node)Nos movemos por la gramática analizando todos los hijos de cada elemento p,
def do_p(self, node):
...
if doit:
for child in node.childNodes: self.parse(child)sustituyendo elementos choice con un hijo al azar,
def do_choice(self, node):
self.parse(self.randomChildElement(node))y los elementos xref con un hijo al azar del elemento ref correspondiente, que pusimos anteriormente en la caché.
def do_xref(self, node):
id = node.attributes["id"].value
self.parse(self.randomChildElement(self.refs[id]))Con el tiempo el análisis llegará al texto plano,
def parse_Text(self, node):
text = node.data
...
self.pieces.append(text)que imprimiremos.
def main(argv): ... k = KantGenerator(grammar, source) print k.output()
<< Tratamiento de los argumentos en línea de órdenes |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Resumen >> |