Pergunta

Estou escrevendo um programa que usa técnicas genéticas para evoluir equações.Quero poder enviar a função 'mainfunc' para a função 'submit' do Parallel Python.A função 'mainfunc' chama dois ou três métodos definidos na classe Utility.Eles instanciam outras classes e chamam vários métodos.Acho que o que quero é tudo isso em um NAMESPACE.Então, instanciei algumas (talvez devessem ser todas) das classes dentro da função 'mainfunc'.Eu chamo o método Utility de 'generate()'.Se seguissemos sua cadeia de execução, isso envolveria todas as classes e métodos no código.

Agora, as equações são armazenadas em uma árvore.Cada vez que uma árvore é gerada, mutada ou criada, os nós precisam receber uma nova chave para que possam ser acessados ​​a partir de um atributo de dicionário da árvore.A classe 'KeySeq' gera essas chaves.

No Parallel Python, enviarei várias instâncias de 'mainfunc' para a função 'submit' do PP.Cada um deve ser capaz de acessar o 'KeySeq'.Seria bom se todos acessassem a mesma instância do KeySeq para que nenhum dos nós nas árvores retornadas tivesse a mesma chave, mas eu poderia contornar isso, se necessário.

Então:minha pergunta é sobre colocar TUDO no mainfunc.Obrigado (editar) Se eu não incluir tudo no MainFunc, tenho que tentar contar ao PP sobre funções dependentes, etc, passando vários argumentos em vários lugares.Estou tentando evitar isso.

(edição tardia) se ks.next() for chamado dentro da função 'generate(), ele retornará o erro 'NameError:o nome global 'ks' não está definido'

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)
Foi útil?

Solução

Se você quiser todas as instâncias de mainfunc usar o mesmo KeySeq objeto, você pode usar o truque do valor do parâmetro padrão:

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

Contanto que você realmente não passe um valor de ks, todas as chamadas para mainfunc usará a instância de KeySeq que foi criado quando a função foi definida.

Aqui está o porquê, caso você não saiba:Uma função é um objeto.Tem atributos.Um de seus atributos é denominado func_defaults;é uma tupla contendo os valores padrão de todos os argumentos em sua assinatura que possuem padrões.Quando você chama uma função e não fornece um valor para um argumento que possui um padrão, a função recupera o valor de func_defaults.Então, quando você ligar mainfunc sem fornecer um valor para ks, obtém o KeySeq() instância fora do func_defaults tupla.O que, para esse caso de mainfunc, é sempre o mesmo KeySeq instância.

Agora, você diz que vai enviar "múltiplas instâncias de mainfunc para o submit função do PP." Você realmente quer dizer múltiplas instâncias?Nesse caso, o mecanismo que estou descrevendo não funcionará.

Mas é complicado criar múltiplas instâncias de uma função (e o código que você postou não cria).Por exemplo, esta função retorna uma nova instância de g toda vez que é chamado:

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

Se eu ligar g() sem argumento, ele retorna o valor padrão (inicialmente uma lista vazia) de seu func_defaults tupla.Desde g1 e g2 são instâncias diferentes do g função, seu valor padrão para o x argumento é também uma instância diferente, que o acima demonstra.

Se você quiser tornar isso mais explícito do que usar um efeito colateral complicado de valores padrão, aqui está outra maneira de fazer isso:

def função principal():se não for hasattr(mainfunc, "ks"):setAtTr (mainfunc, "ks", keyseq ()) key = mainfunc.ks.next ()

Por fim, um ponto super importante que o código que você postou ignora:Se você pretende fazer processamento paralelo em dados compartilhados, o código que toca esses dados precisa implementar o bloqueio.Olhe para a callback.py exemplo na documentação do Parallel Python e veja como o bloqueio é usado no Sum aula e por quê.

Outras dicas

Não há problema em estruturar seu programa dessa maneira.Muitos utilitários de linha de comando seguem o mesmo padrão:

#imports, utilities, other functions

def main(arg):
    #...

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

Dessa forma você pode ligar para o main função de outro módulo importando-o ou você pode executá-lo a partir da linha de comando.

Seu conceito de classes em Python não é bom, eu acho.Talvez fosse uma boa ideia revisar o básico.Este link ajudará.

Noções básicas de Python - aulas

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top