在Python类列表中引用类方法

4 投票
7 回答
14784 浏览
提问于 2025-04-15 13:57

我正在写一个Python 2.6.2的类,这个类里面有一个查找表。大部分情况下,这个表里存的是简单的数据。不过,有些情况比较复杂,我想调用一个函数来处理。但是,我在引用这个函数的时候遇到了一些麻烦。

下面是一些示例代码:

class a:
    lut = [1,
           3,
           17,
           [12,34],
           5]

这里的lut是静态的,应该是常量。

现在我想做以下事情:

class a:
    def spam0(self):
        return (some_calculation_based_on_self)

    def spam1(self):
        return (a_different_calculation_based_on_self)

    lut = [1,
           3,
           17,
           [12,34],
           5,
           self.spam0
           self.spam1]

这段代码不能编译,因为self.spam0self.spam1是未定义的。我试着用a.spam,但那也是未定义的。我该怎么做才能让lut[5]返回self.spam的引用呢?

编辑:这是我计划要做的:

(继续定义class a):

import inspect

# continue to somewhere in the definition of class a

def __init__(self, param):
    self.param = param

def eggs(self):
    tmp = lut[param]
    if (insect.isfunction(tmp)): # if tmp is self.spam()
        return tmp()             # should call it here
    return tmp

所以我想根据参数的不同,返回一个简单的值或者运行一些额外的代码。

编辑:其实lut不一定要是类的属性,但方法spam0spam1需要访问类的成员,所以它们必须属于这个类。

我不确定这是不是最好的做法。我还在努力解决这个问题。

7 个回答

4

当你在这个类的范围内时,你可以直接写

class A:
    def spam(self):
        pass

    lut = [1, 2, 3, spam]

a = A()
print a.lut

这样会得到

[1, 2, 3, <function spam at 0xb7bb764c>]

别忘了,这其实是你查找表中的一个函数,而不是你可能想要的数字。你可能需要解决另一个问题。

4

在类的主体部分,你正在创建这个类;这里没有 self,所以你显然不能使用 self.anything。而且在这个主体内,a 这个名字是在类的主体完成后才被绑定的。因此,虽然这点不太明显,但在类 a 的主体中,你也不能引用 a.anything

你可以引用的是已经绑定的类属性的简单名字:比如,你可以在你的列表 lut 的末尾直接使用 5, spamspam 会作为一个函数存在,因为你在某个地方说过你想要这样;而不是作为一个方法,更不是作为一个类方法(我在你的代码中没有看到 classmethod,你为什么认为类方法会神奇地出现,除非你明确地把一个函数用 classmethod 包裹起来,无论是直接使用还是通过装饰器?)-- 我怀疑你所说的“类方法”实际上并不指代类方法类型(虽然这确实让人困惑;-)。

所以,如果你后来需要在某个 a 的实例 x 上调用那个函数,你将会像这样调用:a.lut[-1](x),参数是明确给出的。

如果你需要做一些更复杂的事情,可能在处理的不同阶段(类创建完成后,或者如果你想要一个绑定的实例方法,只有在特定实例被创建后)可以获取某种绑定或未绑定的方法。但你没有清楚和完整地解释你到底想做什么,所以我们无法提供非常详细的帮助来解决这些后续的选择。

0

简单来说:

class a:
    @classmethod
    def spam(cls):
        # not really pass, but you get the idea
        pass

    lut = [1,
           3,
           17,
           [12,34],
           5,
           spam]


assert a().lut[-1] == a.spam
assert a.spam() is None

撰写回答