Python的优良做法:将变量名称作为参数

时间:2013-06-26 08:44:59

标签: python python-2.7

很确定我知道这个问题的答案,但是想问问python社区。

我正在开发一个python项目,目前的趋势是剪切变量名或类名,将其作为参数传递给其他方法...赞:

myVar.__classname__[6:] 

或最差:

try :
    ...
except Error as err :
    myVar = err.message.split(':')[0]
    getattr(myInst, myVar)
等等......那就是说,我们必须尊重一个非常严格的命名惯例,这些约定符合所有那些可怕的代码行,但我想知道这是否是一种常见的做法,而且我完全脱离了行或如果我说这只是......太可怕了。

对我来说这似乎是一个非常糟糕的主意,但我们别无选择......

感谢任何有助于我的回复

编辑:这是try / except中的实际代码,如果您想了解更多详细信息:

except ValueError as err:
    field_error = self.klass.__name__ + '_' + err.message.split(':')[0]
    getattr(self.ui, field_error).setText(err.message) 

编辑:所以有些人要求提供更多细节:

在上面的示例中,我们想在用户输入的值错误时在字段中设置错误消息。

self.klass表示一个SQL Alchemy类,“命名约定”表示每个字段应该以它前面的SQL Alchemy类名开头,然后是下划线,然后是我们设置错误消息的字段(目前与用户输入错误相同。)

这将“构建”(哦上帝......这感觉很糟糕)ui字段的名称是错误的,然后我们将通过ui上的getattr得到它。

这感觉非常错误,因为它基于一个命名约定,当我们开始有更多类时可能有数十亿例外...实际上,我不介意修复它,但整个项目是基于这个命名惯例。第一个例子基于这样一个事实:我们的应用程序有不同的ui文件,并且这些文件由代码索引(如7CDGR01)。然后由类完成这些以添加行为(信号处理......等)。如果我保留相同的示例,则该类名为:Screen7CDGR01。因此,要获得屏幕的代码,您可以从第6个字符开始获取类名的结尾...然后将其发送到另一个方法等等...

认为你们都得到了它,这不是我投票的,我认为这只是坏事,我不是python的专家,但我认为即使python允许我们做很多事情,它也不应该是像那样使用。

2 个答案:

答案 0 :(得分:3)

对变量/类名使用内省很危险,因为在Python中,名称不一致:Python introspection: access function name and docstring inside function definition

#!/usr/local/bin/python2.7


class myInst(): 
  iitt = 15
  pass

class deco():
    def __init__(self, id, *args, **kws):
        self.__id = id
        self.iitt = 25
        self.__name__ = "another name"

@deco
class myInst2():
  iitt = 15
  pass


# Overriding class name
print "MyInst name :", myInst.__name__    #"myInst"
print "MyInst2 name :", myInst2.__name__  #"another name"


# Overriding attribute value
try:
  raise ValueError("iitt: Error!")
except ValueError as err:
  myVar = err.message.split(':')[0]
  l = getattr(myInst, myVar)
  print l                                 # 15

try:
  raise ValueError("iitt: Error!")
except ValueError as err :
  myVar = err.message.split(':')[0]
  l = getattr(myInst2, myVar)
  print l                                 # 25

#Duck Typing
myInst = myInst2
try:
  raise ValueError("iitt: Error!")
except ValueError as err :
  myVar = err.message.split(':')[0]
  l = getattr(myInst, myVar)
  print l                                 # 25

答案 1 :(得分:2)

除了关于装饰器的内容之外,重要的是要知道这种代码很难阅读。

Python因其可读性而闻名,例如

err.message.split(':')[0]

非常很难被项目中的新人理解。仅仅建议可以做些什么:

Except ValueError as valueError:
    validationError = new ValidationError(valueError)
    componentSelector = validationError.getComponentSelector(self.getClassName())
    getattr(self.ui, componentSelector).setText(validationError.message)

这样,所有不可读的代码都封装在getComponentSelector()方法中。这只是可能的解决方案之一。

如果您想知道使用Python编程时有什么好处和坏处,请花些时间阅读https://stackoverflow.com/questions/228181/zen-of-python