Pregunta

He estado pensando en esto demasiado tiempo y no han recibido ninguna idea, tal vez algunos de ustedes puede ayudar.

tengo una carpeta de scripts de Python, todos los cuales tienen el mismo cuerpo que rodea (literalmente, me genera desde un script de shell), pero tienen un trozo que es diferente a todos ellos. En otras palabras:

Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)

Y me di cuenta hoy que esto es una mala idea, por ejemplo, si quiero cambiar algo de la parte superior o secciones inferiores, que tienen que escribir un script para hacerlo. (No es que eso es difícil, sólo parece que es un código muy mala en cuanto a).

Así que lo que quiero hacer, es tener un script en Python externa que es de esta manera:

Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code

Y entonces cada otro archivo en la carpeta de pitón puede ser simplemente la pieza central de código. Sin embargo, el módulo normal no funcionaría aquí (si no me equivoco), porque me gustaría obtener el código que necesito para ejecutar desde el argumento, lo que sería una cadena, por lo que no sabría qué función se ejecute hasta el tiempo de ejecución .

Así que pensé dos soluciones más:

  1. Podría escribir un montón de si las declaraciones, uno para ejecutar cada una escritura basada en un determinado parámetro. Rechacé esto, ya que es aún peor que el diseño anterior.
  2. Podría usar:

    os.command (sys.argv [0] scriptName.py)

    lo que iría en el guión, pero llamar pitón a pitón llamada no parece muy elegante para mí.

Así que, ¿alguien tiene alguna otra idea? Gracias.

¿Fue útil?

Solución

Si conoce el nombre de la función como una cadena y el nombre del módulo como una cadena, entonces puede hacerlo

mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()

Otros consejos

Otra posible solución es tener cada uno de sus archivos repetitivos importar la funcionalidad del archivo principal

from topAndBottom import top, bottom
top()
# do middle stuff
bottom()

Además de las varias respuestas ya publicadas, considere la Plantilla Método patrón de diseño: hacer una clase abstracta como

class Base(object):
    def top(self): ...
    def bottom(self): ...
    def middle(self): raise NotImplementedError
    def doit(self):
        self.top()
        self.middle()
        self.bottom()

Cada módulo conectable a continuación, hace que una clase que hereda de esta Base y tendrá prioridad sobre middle con el código correspondiente.

Tal vez no pueda garantizarse en este caso sencillo (usted todavía tiene que importar el módulo adecuado con el fin de crear una instancia de su clase y llamada doit en él), pero todavía vale la pena teniendo en cuenta (junto con sus muchas variaciones Pythonic, que tengo ampliamente explicado en muchas conversaciones tecnología ya está disponible en youtube) para los casos en los que el número o la complejidad de "piezas enchufables" sigue creciendo - Template Method (a pesar de su nombre horrible ;-) es un sólido, bien probada y altamente escalable patrón [[ a veces un poco demasiado rígida, pero eso es exactamente lo que trato en esas muchas charlas técnicas - y ese problema no se aplica a este caso de uso específico]]

.
  

Sin embargo, el módulo normal sería no trabajar aquí (si no me equivoco), porque me gustaría obtener el código que necesito para ejecutar desde el argumento, lo que sería una cadena, por lo que no sabría que funcionan a extenderá hasta el tiempo de ejecución.

Se trabajará muy bien - el uso __import__ incorporada o, si tienen muy complejo diseño, imp módulo para importar su guión. Y entonces se puede obtener mediante la función module.__dict__[funcname] por ejemplo.

Importación de un módulo (como se explica en otras respuestas) es sin duda la forma más limpia de hacer esto, pero si por alguna razón esto no funciona, siempre y cuando usted no está haciendo nada demasiado extraño puede utilizar exec . Básicamente ejecuta el contenido de otro archivo como si estuviera incluido en el archivo actual en el punto donde exec se llama. Es lo más parecido a Python tiene una declaración source del tipo incluido en muchas conchas. Como mínimo, algo como esto debería funcionar:

exec(open(filename).read(None))

¿Qué tal esto?

function do_thing_one():
   pass

function do_thing_two():
   pass

dispatch = { "one" : do_thing_one,
             "two" : do_thing_two,
           }

# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"

# do top thing
f = dispatch[mystring]
f()
# do bottom thing
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top