PythonRecipe--变量缩写

这篇文章翻译自activecode的文章Variable Abbreviations

这篇文章属于专题Python Recipe

变量有时可能会有一个很长的易读的名称,比如buildingList[foundIndex].height,不过在一些类似公式或类似的情况下,如果出现太多过长名称的变量可能会搞混读者。物理学家出于这个原因使用"单字母变量名(one-letter names)"

出于这个原因,我写了一个简单的上下文管理器。可以使用简单的变量名来代替长变量名:

with Abbr(h=buildingList[foundIndex].height, g=gravitationalConstant):
    fallTime = sqrt(2 * h / g)
    endSpeed = sqrt(2 * h * g)
print("Fall time:", fallTime)
print("End speed:", endSpeed)

对于较长公式来说,这种方式可以减少那种丑陋的多行表达式的情况。

也可以这样写:

h = buildingList[foundIndex].height
g = gravitationalConstant
fallTime = sqrt(2 * h / g)
endSpeed = sqrt(2 * h * g)
del g, h
print("Fall time:", fallTime)
print("End speed:", endSpeed)

上面的代码可以达到相同的效果,不过:

  • 后者看起来不如前者那么清晰
  • 上下文管理器的方式可以像一般处理exception那样清理变量

当然,你也可以选择不删除那些短的局部变量,但是这会搞乱命名空间。

警告:Abbr()是以hack的方式实现的。它是为了本文讨论的目的而实现的。但是因为它的hack,所以有些事情需要提及:由于编译时编译器例子中的hg必须是全局变量(因为不是在函数中赋值),它会生成一个byte code来访问全局变量。上下文管理器会对全局变量结构(globals())作些改动。这意味着:

  • 不可以在上下文管理的代码块中再赋值一个相同名称的局部变量。
  • 在上下文管理器的生命周期内,已存的全局变量将会被修改;所以使用类似sysos这种缩写名称会造成副作用。
class Abbr(object):
  def __init__(self, **kwargs):
    self.abbrs = kwargs
    self.store = {}              # 用来临时存储一些被替换的全局变量

  def __enter__(self):
    for key, value in self.abbrs.iteritems():
      try:
        self.store[key] = globals()[key]
      except KeyError:
        pass
      globals()[key] = value

  def __exit__(self, *args, **kwargs):
    for key in self.abbrs:
      try:
        globals()[key] = self.store[key]
      except KeyError:
        del globals()[key]

你可能感兴趣的:(PythonRecipe--变量缩写)