【问题标题】:Alternative to locals() in printing a table with a header替代 locals() 打印带有标题的表格
【发布时间】:2010-11-01 08:25:26
【问题描述】:

[Python 3.1]

编辑:原代码中的错误。

我需要打印一张表格。第一行应该是一个标题,它由制表符分隔的列名组成。以下行应包含数据(也是制表符分隔的)。

为了澄清,假设我有“速度”、“功率”、“重量”列。我最初在related question 的帮助下编写了以下代码:

column_names = ['speed', 'power', 'weight']

def f(row_number):
  # some calculations here to populate variables speed, power, weight
  # e.g., power = retrieve_avg_power(row_number) * 2.5
  # e.g., speed = math.sqrt(power) / 2
  # etc.
  locals_ = locals()
  return {x : locals_[x] for x in column_names}

def print_table(rows):
  print(*column_names, sep = '\t')
  for row_number in range(rows):
    row = f(row_number)
    print(*[row[x] for x in component_names], sep = '\t')

但后来我知道我应该avoid using locals() if possible

现在我被困住了。我不想多次键入所有列名的列表。我不想依赖这样一个事实,即我在f() 中创建的每个字典都可能以相同的顺序遍历其键。而且我不想使用locals()

请注意,print_table()f() 函数还有很多其他功能;所以我必须把它们分开。

我应该如何编写代码?

【问题讨论】:

    标签: python python-3.x list-comprehension locals


    【解决方案1】:
    class Columns:
        pass
    
    def f(row_number):
        c = Columns()
        c.power = retrieve_avg_power(row_number) * 2.5
        c.speed = math.sqrt(power) / 2
        return c.__dict__
    

    这还可以让您指定哪些变量作为列,而不是在函数中是临时的。

    【讨论】:

    • 这是否与创建字典 columns = {} 并像这样填充它基本相同:columns['speed'] = math.sqrt(columns['power'])/2
    • 顺便说一句,对于优化器来说,使用__dict__ 比使用locals() 问题少吗?
    • 确实如此,只是我发现属性语法更易于阅读和键入。
    • 存储到对象中比存储到局部变量中要昂贵得多。所以你不应该在循环中分配给 c.power 。但是,由于您最终需要将值全部存储在字典中,因此不涉及任何成本。优化器的问题是:如果使用 locals(),它们还需要停止使用对局部变量的有效访问(这样它们实际上变得比实例属性慢)。
    【解决方案2】:

    您可以使用OrderedDict 来修复字典的顺序。但在我看来,这甚至没有必要。您总是从column_names 列表中获取键(最后一行除外,我认为这是一个错字),因此值的顺序将始终相同。

    【讨论】:

    • 我认为没有locals() 并且不重复名称很难填充OrderedDict。 (另外,请注意,我计算变量的顺序不一定与输出表中所需的列顺序相同。)
    • @max:好的,现在我明白问题所在了。
    【解决方案3】:

    locals() 的替代方法是使用 inspect 模块

    import inspect
    
    def f(row_number):
        # some calculations here to populate variables speed, power, weight
        # e.g., power = retrieve_avg_power(row_number) * 2.5
        # e.g., speed = math.sqrt(power) / 2
        # etc.
        locals_ = inspect.currentframe().f_locals
        return {x : locals_[x] for x in column_names }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-06
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 2020-10-28
      • 2017-04-22
      相关资源
      最近更新 更多