构建一个程序。 Python 中的类和函数

发布于 2024-08-07 03:09:04 字数 1395 浏览 5 评论 0原文

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

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

在并行 Python 中,我将把“mainfunc”的多个实例发送到 PP 的“submit”函数。每个人都必须能够访问“KeySeq”。如果它们都访问相同的 KeySeq 实例,这样返回的树上没有一个节点具有相同的密钥,那就太好了,但如果有必要,我可以解决这个问题。

所以:我的问题是关于将所有内容都填充到 mainfunc 中。 谢谢 (编辑)如果我没有将所有内容都包含在 mainfunc 中,我必须尝试通过在不同地方传递各种参数来告诉 PP 有关依赖函数等的信息。我正在努力避免这种情况。

(后期编辑)如果 ks.next() 在 'generate() 函数内调用,它将返回错误 'NameError: 全局名称 'ks' 未定义'

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)

I'm writing a program that uses genetic techniques to evolve equations.
I want to be able to submit the function 'mainfunc' to the Parallel Python 'submit' function.
The function 'mainfunc' calls two or three methods defined in the Utility class.
They instantiate other classes and call various methods.
I think what I want is all of it in one NAMESPACE.
So I've instantiated some (maybe it should be all) of the classes inside the function 'mainfunc'.
I call the Utility method 'generate()'. If we were to follow it's chain of execution
it would involve all of the classes and methods in the code.

Now, the equations are stored in a tree. Each time a tree is generated, mutated or cross
bred, the nodes need to be given a new key so they can be accessed from a dictionary attribute of the tree. The class 'KeySeq' generates these keys.

In Parallel Python, I'm going to send multiple instances of 'mainfunc' to the 'submit' function of PP. Each has to be able to access 'KeySeq'. It would be nice if they all accessed the same instance of KeySeq so that none of the nodes on the returned trees had the same key, but I could get around that if necessary.

So: my question is about stuffing EVERYTHING into mainfunc.
Thanks
(Edit) If I don't include everything in mainfunc, I have to try to tell PP about dependent functions, etc by passing various arguements in various places. I'm trying to avoid that.

(late Edit) if ks.next() is called inside the 'generate() function, it returns the error '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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

人疚 2024-08-14 03:09:04

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

#imports, utilities, other functions

def main(arg):
    #...

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

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

It's fine to structure your program that way. A lot of command line utilities follow the same pattern:

#imports, utilities, other functions

def main(arg):
    #...

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

That way you can call the main function from another module by importing it, or you can run it from the command line.

烟酒忠诚 2024-08-14 03:09:04

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

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

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

如果您不知道的话,原因如下:函数是一个对象。它有属性。它的属性之一名为func_defaults;它是一个元组,包含其签名中具有默认值的所有参数的默认值。当您调用函数并且不为具有默认值的参数提供值时,该函数将从 func_defaults 检索该值。因此,当您调用 mainfunc 而不提供 ks 值时,它会从 func_defaults 中获取 KeySeq() 实例> 元组。对于该 mainfunc 实例,它始终是相同的 KeySeq 实例。

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

但是创建一个函数的多个实例是很棘手的(并且您发布的代码则不然)。例如,此函数每次调用时都会返回一个新的 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(),它会返回默认值(最初是一个空值) list)来自其 func_defaults 元组。由于 g1g2g 函数的不同实例,因此它们的 x 参数的默认值为 还有一个不同的实例,如上面所演示的。

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

def mainfunc():
如果不是 hasattr(mainfunc, "ks"):
setattr(mainfunc, “ks”, KeySeq())
key = mainfunc.ks.next()

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

If you want all of the instances of mainfunc to use the same KeySeq object, you can use the default parameter value trick:

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

As long as you don't actually pass in a value of ks, all calls to mainfunc will use the instance of KeySeq that was created when the function was defined.

Here's why, in case you don't know: A function is an object. It has attributes. One of its attributes is named func_defaults; it's a tuple containing the default values of all of the arguments in its signature that have defaults. When you call a function and don't provide a value for an argument that has a default, the function retrieves the value from func_defaults. So when you call mainfunc without providing a value for ks, it gets the KeySeq() instance out of the func_defaults tuple. Which, for that instance of mainfunc, is always the same KeySeq instance.

Now, you say that you're going to send "multiple instances of mainfunc to the submit function of PP." Do you really mean multiple instances? If so, the mechanism I'm describing won't work.

But it's tricky to create multiple instances of a function (and the code you've posted doesn't). For example, this function does return a new instance of g every time it's called:

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

If I call g() with no argument, it returns the default value (initially an empty list) from its func_defaults tuple. Since g1 and g2 are different instances of the g function, their default value for the x argument is also a different instance, which the above demonstrates.

If you'd like to make this more explicit than using a tricky side-effect of default values, here's another way to do it:

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

Finally, a super important point that the code you've posted overlooks: If you're going to be doing parallel processing on shared data, the code that touches that data needs to implement locking. Look at the callback.py example in the Parallel Python documentation and see how locking is used in the Sum class, and why.

花开半夏魅人心 2024-08-14 03:09:04

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

Python 基础知识 - 类

Your concept of classes in Python is not sound I think. Perhaps, it would be a good idea to review the basics. This link will help.

Python Basics - Classes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文