5

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

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

myVar.__classname__[6:] 

或最差:

try :
    ...
except Error as err :
    myVar = err.message.split(':')[0]
    getattr(myInst, myVar)

等等......也就是说,我们必须尊重一个非常严格的命名约定,该约定将适合所有那些可怕的代码行,但我想知道这是否是一种常见的做法,我完全不合规矩,或者我是正确地说这只是......可怕。

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

感谢您对我有帮助的任何回复

编辑:这是尝试中的实际代码/除非您想了解更多详细信息:

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允许我们做很多事情,也不应该那样使用它.

4

2 回答 2

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
于 2013-06-26T10:45:22.097 回答
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

于 2013-06-28T07:45:09.243 回答