__以函数为参数的初始化(使用NetworkX)

2024-04-26 07:42:38 发布

您现在位置:Python中文网/ 问答频道 /正文

问题

我希望能够用引用实例属性的函数初始化对象。我想在这个片段中捕获的是,它产生了一个NameError: "global name 'self' is not defined"

class Test(object):
    def __init__(self, function = None):
        self.dicty = {1:{'height': 4, 'width': 2}, 2:{'height': 1, 'width': 2} }
        if function == None:
            self.function = lambda x : self.dicty[x]['height']
        else:
            self.function = function

if __name__ == '__main__':
    def func1(x):
        return self.dicty[x]['width']
    def func2(x):
        return self.dicty[x]['width']**2
    G = Test(function = func1)
    H = Test(function = func2)

我可以通过为Test创建一堆子类来解决这个问题,但这似乎不可读。你知道吗

动机

我正在使用NetworkX做Python建模和实验。我正在研究经典的Albert-Barabasi Model,并创建有向图类的子类,其中包括Preference(self, node)Attachment(self, parent, child),然后是Grow(self, max_allowable_nodes)。我希望能够创建一个修改preference()的实例,而不是像前面提到的那样创建一大堆子类。这将允许我运行数值实验,而不会让我的代码看起来太像弗兰肯斯坦。期待着学习新的东西。你知道吗

编辑:

不知道types类或反射的一般思想。显然,这里还是很新的。真的很感谢大家回答我的问题,并指出我在正确的方向!你知道吗


Tags: 实例nametestselfnonereturnifdef
2条回答

定义func1时,没有self这样的东西。它不是函数的参数,也不在任何更高的范围内。你知道吗

相反,您可以定义一个函数,该函数将使用的dict作为参数并对其进行操作。在Test类中,可以调用self.dicty上的函数。这将要求您将lambda更改为同时使用dictyx,而不是只使用x。你知道吗

def func1(dicty, x):
    return dicty[x]['width']

…在Test。。。你知道吗

class Test(object):

    # ... current code but with lambda tweak:
    # lambda dicty, x: dicty[x]['height']

    def do_something(self, x):
        self.function(self.dicty, x)

如果看不到代码的其余部分,就很难知道可以做哪些进一步的简化。但由于所有函数似乎都在使用dicty[x],所以您可以直接编写它们。你知道吗

假设您在__init__中创建的lambda引用实例(self),看起来您希望将一个方法附加到实例,而这里您附加的是一个函数。您需要从函数创建方法并将其附加到实例:

import types

class Test(object):
    def __init__(self, function = None):
        self.dicty = {1:{'height': 4, 'width': 2}, 2:{'height': 1, 'width': 2} }
        if function == None:
            function = lambda self, x: self.dicty[x]['height']
        self.function = types.MethodType(function, self)

方法基本上是一个函数,它总是将实例作为第一个参数传递,因此需要确保传递给初始化器的任何函数都将self作为初始参数。你知道吗

>>> t1 = Test()
>>> t1.function(1)
4

>>> t2 = Test(lambda self, x: self.dicty[x]['width'])
>>> t2.function(1)
2

相关问题 更多 >