5

私はこの質問に対する答えを知っていると確信していますが、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で多くのことができるとしても、そのように使用すべきではないと思います.

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() メソッド内にカプセル化されます。そして、これは可能な解決策の 1 つにすぎません。

Python でプログラミングする際の良い点と悪い点を知りたい場合は、時間をかけて https://stackoverflow.com/questions/228181/zen-of-pythonを読んでください。

于 2013-06-28T07:45:09.243 に答える