简体   繁体   English

A python function 返回带有 for 循环的 function 列表

[英]A python function that return a list of function with a for loop

I am trying to implement a function (make_q) that returns a list of functions(Q) that are generated using the argument that make_q gets (P).我正在尝试实现一个 function (make_q),它返回使用 make_q 获取的参数 (P) 生成的函数 (Q) 列表。 Q is a variable dependent to n(=len(P)) and making the Q functions are similar, so it can be done in a for loop but here is the catch if I name the function in the loop, they will all have the same address so I only get the last Q, Is there to bypass this? Q 是一个依赖于 n(=len(P)) 的变量,并且使 Q 函数相似,因此可以在 for 循环中完成,但如果我在循环中将 function 命名为,它们都将具有相同的地址,所以我只得到最后一个 Q,有没有绕过这个? Here is my code,这是我的代码,

 def make_q(self):
        Temp_P=[p for p in self.P]
        Q=()
        for i in range(self.n-1):
            p=min(Temp_P)
            q=max(Temp_P)
            index_p=Temp_P.index(p)
            index_q=Temp_P.index(q)
            
            def tempQ():
                condition=random.random()
                if condition<=(p*self.n):
                    return index_p
                else:
                    return index_q
            Temp_Q=list(Q)
            Temp_Q.append(tempQ)
            Q=tuple(Temp_Q)
            q-=(1-p*self.n)/self.n
            Temp_P[index_q]=q
            Temp_P.pop(index_p)

        return Q
test.Q

(<function __main__.Test.make_q.<locals>.tempQ()>,
 <function __main__.Test.make_q.<locals>.tempQ()>,
 <function __main__.Test.make_q.<locals>.tempQ()>,
 <function __main__.Test.make_q.<locals>.tempQ()>,
 <function __main__.Test.make_q.<locals>.tempQ()>)

I also tried to make them a tuple so they have different addresses but it didn't work.我还尝试将它们设为元组,以便它们具有不同的地址,但它不起作用。 Is there a way to name functions(tempQ) dynamic like tempQi有没有办法像tempQi一样dynamic命名函数(tempQ)

jasonharper's observation and solution in comments is correct(and should be the accepted answer). jasonharper 在评论中的观察和解决方案是正确的(应该是公认的答案)。 But since you asked about metaclasses, I am posting this anyway.但既然你问到元类,我还是把这个贴出来。

In python, each class is a type , with "name", "bases" (base classes) and "attrs"(all members of a class).在 python 中,每个 class 都是一个type ,有“name”、“bases”(基类)和“attrs”(类的所有成员)。 Essentially, a metaclass defines a behaviour of a class, you can read more about it at https://www.python-course.eu/python3_metaclasses.php and various other online tutorials.本质上,元类定义了 class 的行为,您可以在https://www.python-course.eu/python3_metaclasses.ZE1BFD762321E409CEE4AC0B6E841963C和其他各种在线教程中了解更多信息。

The __new__ method runs when a class is set up. __new__方法在设置 class 时运行。 Note the usage of attrs where your class member self.n is accessed by attrs['n'] (as attrs is a dict of all class members).请注意attrs的用法,其中您的 class 成员self.nattrs['n']访问(因为 attrs 是所有 class 成员的字典)。 I am defining functions tempQ_0, tempQ_1... dynamically.我正在动态定义函数tempQ_0, tempQ_1... As you can see, we can also add docstrings to this dynamically defined class members.如您所见,我们还可以将文档字符串添加到这个动态定义的 class 成员中。

import random


class MyMetaClass(type):

    def __new__(cls, name, bases, attrs):
        Temp_P = [p for p in attrs['P']]
        for i in range(attrs['n'] - 1):
            p = min(Temp_P)
            q = max(Temp_P)
            index_p = Temp_P.index(p)
            index_q = Temp_P.index(q)

            def fget(self, index_p=index_p, index_q=index_q):  # this is an unbound method
                condition = random.random()
                return index_p if condition <= (p * self.n) else index_q

            attrs['tempQ_{}'.format(i)] = property(fget, doc="""
            This function returns {} or {} randomly""".format(index_p, index_q))

            q -= (1 - p * attrs['n']) / attrs['n']
            Temp_P[index_q] = q
            Temp_P.pop(index_p)

        return super(MyMetaClass, cls).__new__(cls, name, bases, attrs)


# PY2
# class MyClass(object):
#     __metaclass__ = MyMetaClass
#     n = 3
#     P = [3, 6, 8]


# PY3
class MyClass(metaclass=MyMetaClass):
    n = 3
    P = [3, 6, 8]

# or use with_metaclass from future.utils for both Py2 and Py3

# print(dir(MyClass))
print(MyClass.tempQ_0, MyClass.tempQ_1)

output output

<property object at 0x10e5fbd18> <property object at 0x10eaad0e8>

So your list of functions is [MyClass.tempQ_0, MyClass.tempQ_1]所以你的函数列表是[MyClass.tempQ_0, MyClass.tempQ_1]

Please try via formatted strings, for eg: "function_{}.format(name)" also, how do you want your output to look like?请尝试通过格式化字符串,例如:“function_{}.format(name)”,您希望您的 output 看起来如何?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM