3

我正在编写一个程序,该程序使用遗传技术来演化方程。我希望能够将函数 'mainfunc' 提交给 Parallel Python 'submit' 函数。函数“mainfunc”调用了在 Utility 类中定义的两个或三个方法。它们实例化其他类并调用各种方法。我想我想要的就是一个 NAMESPACE 中的所有内容。所以我已经实例化了函数'mainfunc'中的一些(也许应该是全部)类。我将实用程序方法称为“generate()”。如果我们要遵循它的执行链,它将涉及代码中的所有类和方法。

现在,方程存储在树中。每次生成、变异或杂交一棵树时,都需要为节点提供一个新键,以便可以从树的字典属性中访问它们。“KeySeq”类生成这些密钥。

在 Parallel Python 中,我将发送多个 'mainfunc' 实例到 PP 的 'submit' 函数。每个人都必须能够访问“KeySeq”。如果他们都访问相同的 KeySeq 实例,这样返回的树上的所有节点都没有相同的键,那就太好了,但如果有必要我可以绕过它。

所以:我的问题是关于把所有东西都塞进mainfunc。谢谢(编辑)如果我没有在 mainfunc 中包含所有内容,我必须通过在各个地方传递各种争论来尝试告诉 PP 有关依赖函数等。我试图避免这种情况。

(后期编辑)如果 ks.next() 在 'generate() 函数内被调用,它会返回错误'NameError: global name 'ks' is not defined'

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)
4

3 回答 3

3

以这种方式构建您的程序很好。许多命令行实用程序都遵循相同的模式:

#imports, utilities, other functions

def main(arg):
    #...

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

这样,您可以main通过导入从另一个模块调用该函数,也可以从命令行运行它。

于 2009-10-13T16:34:00.023 回答
1

如果您希望 的所有实例mainfunc使用相同的KeySeq对象,您可以使用默认参数值技巧:

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

只要您实际上没有传入 的值ks,所有对 的调用都将使用在定义函数时创建mainfunc的实例。KeySeq

如果您不知道,这就是为什么:函数是对象。它有属性。它的属性之一是命名func_defaults;它是一个元组,包含其签名中具有默认值的所有参数的默认值。当您调用一个函数并且没有为具有默认值的参数提供值时,该函数会从func_defaults. 因此,当您在mainfunc没有为 提供值的情况下调用时ks,它会将KeySeq()实例从func_defaults元组中取出。哪个,对于那个实例mainfunc,总是同一个KeySeq实例。

现在,您说您要发送“多个PP 函数的实例” mainfuncsubmit你真的是指多个实例吗?如果是这样,我所描述的机制将不起作用。

但是创建一个函数的多个实例很棘手(您发布的代码没有)。例如,此函数g每次调用时都会返回一个新实例:

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

如果我g()不带参数调用,它会从其func_defaults元组返回默认值(最初是一个空列表)。由于g1g2是函数的不同实例,因此它们的参数g默认值也是不同的实例,如上所示。x

如果您想让这比使用默认值的棘手副作用更明确,这里有另一种方法:

def mainfunc(): if not hasattr(mainfunc, "ks"): setattr(mainfunc, "ks", KeySeq()) key = mainfunc.ks.next()

最后,您发布的代码忽略了一个非常重要的一点:如果您要对共享数据进行并行处理,则涉及该数据的代码需要实现锁定。查看callback.pyParallel Python 文档中的示例,了解如何在Sum类中使用锁定,以及为什么。

于 2009-10-14T00:26:26.007 回答
0

我认为您在 Python 中的类概念并不合理。也许,回顾一下基础知识是个好主意。这个链接会有所帮助。

Python 基础 - 类

于 2009-10-16T10:01:41.460 回答