Pregunta

Estoy escribiendo un programa que utiliza técnicas genéticas para desarrollar ecuaciones. Quiero ser capaz de presentar la función 'mainfunc' a la función de Python paralelo 'enviar'. La función 'mainfunc' llama a dos o tres métodos definidos en la clase de utilidad. Ellos ejemplifican otras clases y llamar a varios métodos. Creo que lo que quiero es todo ello en un espacio de nombres. Así que he instanciada algunos (tal vez debería ser todo) de las clases dentro de la función 'mainfunc'. Que llamo el método de utilidad 'generar ()'. Si tuviéramos que seguir es la cadena de ejecución porque se trataría de todas las clases y métodos en el código.

Ahora, las ecuaciones se almacenan en un árbol. Cada vez que se genera un árbol, mutado o cruz criado, los nodos deben recibir una nueva clave para que puedan ser accedidos desde un atributo diccionario del árbol. La clase 'sectecla' genera estas claves.

En Python paralelo, voy a enviar varias copias de 'mainfunc' a la función 'enviar' del PP. Cada uno tiene que ser capaz de acceder a 'sectecla'. Sería bueno que todos acceder a la misma instancia de sectecla para que ninguno de los nodos en los árboles volvieron tenían la misma clave, pero pude conseguir alrededor de eso, si es necesario.

Por lo tanto: mi pregunta es sobre todo en el relleno mainfunc. Gracias (Edit) Si no incluyo todo en mainfunc, tengo que tratar de contar PP acerca de las funciones dependientes, etc transmitiéndole varios me lo quitaron en varios lugares. Estoy tratando de evitar eso.

(Editar tarde) si ks.next () es llamado dentro de la 'función de generar (), devuelve el error 'NameError: nombre global 'ks' no está definida'

class KeySeq:
    "Iterator to produce sequential \
    integers for keys in dict"
    def __init__(self, data = 0):
        self.data = data
    def __iter__(self):
        return self
    def next(self):
        self.data = self.data + 1
        return self.data
class One:
    'some code'
class Two:
    'some code'
class Three:
    'some code'
class Utilities:
    def generate(x):
        '___________'
    def obfiscate(y):
        '___________'
    def ruminate(z):
        '__________'


def mainfunc(z):
    ks = KeySeq()
    one = One()
    two = Two()
    three = Three()
    utilities = Utilities()
    list_of_interest = utilities.generate(5)
    return list_of_interest

result = mainfunc(params)
¿Fue útil?

Solución

Si desea que todos los casos de mainfunc a utilizar el mismo objeto KeySeq, puede utilizar el truco valor de parámetro predeterminado:

def mainfunc(ks=KeySeq()):
   key = ks.next()

Mientras no pasa realmente en un valor de ks, todas las llamadas a mainfunc utilizará la instancia de KeySeq que se creó cuando se define la función.

Esto es por qué, en caso de que no sabe: Una función es un objeto. Tiene atributos. Uno de sus atributos es nombrado func_defaults; es una tupla que contiene los valores por defecto de todos los argumentos en su firma que tienen valores predeterminados. Cuando se llama a una función y no proporciona un valor para el argumento de que tiene una forma predeterminada, la función recupera el valor de func_defaults. Así que cuando se llama a mainfunc sin proporcionar un valor para ks, se pone la instancia KeySeq() fuera de los registros func_defaults. Que, por esa instancia de mainfunc, es siempre la misma instancia KeySeq.

Ahora, usted dice que usted va a enviar "varias instancias de mainfunc a la función submit del PP". Es lo que realmente quiere decir varias instancias? Si es así, el mecanismo que estoy describiendo no funcionará.

Pero es difícil de crear varias instancias de una función (y el código que has enviado no lo hace). Por ejemplo, esta función devuelve una nueva instancia de g cada vez que se llama:

>>> def f():
        def g(x=[]):
            return x
        return g
>>> g1 = f()
>>> g2 = f()
>>> g1().append('a')
>>> g2().append('b')
>>> g1()
['a']
>>> g2()
['b']

Si llamo g() sin argumentos, devuelve el valor por defecto (inicialmente una lista vacía) de su tupla func_defaults. Desde g1 y g2 son diferentes instancias de la función g, su valor por defecto para el argumento x es también una instancia diferente, que la anterior demuestra.

Si desea hacer esto más explícito que el uso de un complicado efecto secundario de valores por defecto, aquí hay otra manera de hacerlo:

def mainfunc ():       si no hasattr (mainfunc, "KS"):           SetAttr (mainfunc, "ks", sectecla ())       clave = mainfunc.ks.next ()

Por último, un punto muy importante que el código que has publicado pasa por alto: Si usted va a estar haciendo el procesamiento paralelo de datos compartidos, el código que toca que los datos tiene que aplicar de bloqueo. Mira el ejemplo callback.py en la documentación de Python paralelo y ver cómo se utiliza el bloqueo en la clase Sum, y por qué.

Otros consejos

Está bien para estructurar su programa de esa manera. Una gran cantidad de utilidades de línea de comandos siguen el mismo patrón:

#imports, utilities, other functions

def main(arg):
    #...

if __name__ == '__main__':
    import sys
    main(sys.argv[1])

De este modo puede llamar a la función main de otro módulo mediante su importación, o puede ejecutarlo desde la línea de comandos.

Su concepto de clases en Python no es sólida creo. Tal vez, sería una buena idea revisar los conceptos básicos. Este enlace le ayudará.

Conceptos básicos de Python - Clases

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top