在Python中,有什么优雅的方法在类声明范围内引用类方法吗?

1 投票
4 回答
2174 浏览
提问于 2025-04-16 05:27

下面的代码在Python 2.6和3.1中都能正常运行,但SomeObject.columns中的第三个lambda有点多余,实际上没有什么用,只是为了防止在类声明完成之前去查看SomeObject.helper_function。这看起来像是个小技巧。如果我把这个lambda去掉,直接用SomeObject.helper_function,就会出现NameError: name 'SomeObject' is not defined的错误。难道我没有更好的方法吗?

class SomeObject:
  def __init__(self, values):
    self.values = values

  @staticmethod
  def helper_function(row):
    # do something fancy here
    return str(len(row))

  columns = [
    (lambda x: x['type'], 'Type'),
    (lambda x: 'http://localhost/view?id=%s' % x['id'], 'Link'),
    (lambda x: SomeObject.helper_function(x), 'Data'),
    ]

  def render_table_head(self):
    print('\t'.join([c[1] for c in self.columns]))

  def render_table_body(self):
    for row in self.values:
      print('\t'.join([col[0](row) for col in self.columns]))

4 个回答

0

为什么不在 init() 方法里填充列,并使用 self 呢?

def __init__(self, values):
    self.values = values
    self.columns = [
        (lambda x: x['type'], 'Type'),
        (lambda x: 'http://localhost/view?id=%s' % x['id'], 'Link'),
        (self.helper_function, 'Data'),
    ]
0

这个方法有效。虽然这和我所有的直觉都相悖。

class SomeObject:
  def __init__(self, values):
    self.values = values

  def helper_function(row):
    # do something fancy here
    return str(len(row))

  columns = [
    (lambda x: x['type'], 'Type'),
    (lambda x: 'http://localhost/view?id=%s' % x['id'], 'Link'),
    (helper_function, 'Data'),
    ]

  def render_table_head(self):
    print('\t'.join([c[1] for c in self.columns]))

  def render_table_body(self):
    for row in self.values:
      print('\t'.join([col[0](row) for col in self.columns]))


if __name__ == '__main__':
    print "foo"

    o = SomeObject([{'type':'type100', 'id':'myId'}, {'type':'type200', 'id':'myId2'}])
    o.render_table_body()
4

在定义一个类的时候,不能直接引用这个类本身。其实应该有一些关键词来指代当前的范围,比如可以用 __this_class__ 来表示正在定义的最内层类,用 __this_func__ 来表示正在定义的最内层函数。这样的话,类和函数就可以干净利落地引用自己,而不需要重复写自己的名字。

你可以把列的定义放到类的外面:

class SomeObject:
    def __init__(self, values):
        self.values = values
    ...

SomeObject.columns = [
    (lambda x: x['type'], 'Type'),
    (lambda x: 'http://localhost/view?id=%s' % x['id'], 'Link'),
    (SomeObject.helper_function, 'Data'),
]

顺便提一下,最好使用至少4个空格的缩进。少于这个就很难阅读了。

撰写回答