开发者

In python, any elegant way to refer to class method within the classes declaration scope?

The below code works both under Python 2.6 and 3.1, but the third lambda of SomeObject.columns is a bit silly, serving no real purpose but to prevent the reference to SomeObject.helper_function from being looked at before the class declaration finishes. It seems like a hack. If I remove the lambda, and replace it with just SomeObject.helper_function, I get NameError: name 'SomeObject' is not defined. Am I missing a better non-hacky way?

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

  @staticmethod
  def helpe开发者_StackOverflowr_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]))


There's no way to refer to the class that's currently being defined. There should really be keywords referring to the current scope, eg. __this_class__ for the innermost class being defined and __this_func__ for the innermost function, so classes and functions can cleanly refer to themselves without having to repeat their name.

You could move the definition of columns out of the class body:

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'),
]

By the way, please always use at least 4-space indentation. Anything less is very hard to read.


Why not populate columns in init() and use 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'),
    ]


This works. It goes against all of my sensibilities.

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()


You can directly refer to the static function through

(helper_function.__func__, 'Data'),

without having to change anything else in your code. helper_function is of type staticmethod, and __func__ gives access to the underlying function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜