1

私はコンストラクターの前にクラスで静的フィールド/変数を宣言するために使用されます。Pythonでこれを行うと、エラーが発生します。

クラスの例を次に示します。

class StringCompare:

    methods = OrderedDict()
    # ERROR!:
    #methods['equals'] = equals
    #methods['ends with'] = endswith
    #methods['starts with'] = startswith
    #methods['contains'] = contains

    @staticmethod
    def equals(a, b):
        return a == b

    @staticmethod
    def contains(a, b):
        return a.find(b) != -1

    @staticmethod
    def startswith(a, b):
        return a.startswith(b)

    @staticmethod
    def endswith(a, b):
        return a.endswith(b)

    methods['equals'] = equals
    methods['ends with'] = endswith
    methods['starts with'] = startswith
    methods['contains'] = contains

より洗練された方法はありますか(クラス全体の直後にすべてのステートメントを配置し、アクセスされた各変数の前にStringCompare.)を付けますか?

ここでのベストプラクティスは何ですか?


より複雑なケースは、同じクラス内からコンストラクターを呼び出そうとする場合です。

class Type(InlineFragment):

    # primitive types get None as package name
    def __init__(self, packageName, name, genericType=None):

        ...

    def ...

    primitive = {
        'Character': Type(None, 'char'),
        'Byte'     : Type(None, 'byte'),
        'Short'    : Type(None, 'short'),
        'Integer'  : Type(None, 'int'),
        'Long'     : Type(None, 'long'),
        'Boolean'  : Type(None, 'boolean'),
        'Float'    : Type(None, 'float'),
        'Double'   : Type(None, 'double'),
    }

これにより、エラーが発生します。

\jpa_export_fragments.py", line 361, in Type
    'Character'    : Type(None, 'char'),
NameError: name 'Type' is not defined

これは機能するはずですが、このコードをクラスの外に置くことによってのみこれを解決できます。

4

1 に答える 1

3

一般に、解決策はクラスデコレータを使用することです。あなたの例では、おそらくそれらをクラスメソッドと組み合わせたいと思うでしょう:

def apply_method(attr):
    def apply_to(cls):
        setattr(cls, attr, getattr(cls, '_' + attr)())
        return cls
    return apply_to

@apply_method('primative')
class Type(object):

    def __init__(self, *args):
        pass

    @classmethod
    def _primative(cls):
        return {
    'Character': cls(None, 'char'),
    'Byte'     : cls(None, 'byte'),
    'Short'    : cls(None, 'short'),
    'Integer'  : cls(None, 'int'),
    'Long'     : cls(None, 'long'),
    'Boolean'  : cls(None, 'boolean'),
    'Float'    : cls(None, 'float'),
    'Double'   : cls(None, 'double'),
        }

あなたの最初の例は非常に非Pythonicに見えるので、そのためのデコレータを提案することを躊躇します。代わりに、おそらくstringサブクラスが必要ですか?

class StringCompare(str):
    # none of these are any different from the normal string operations
    # you would really only override ones that are different.

    def __eq__(self, other):
        return super(StringCompare, self).__eq__(other)

    def __contains__(self, other):
        return self.find(other) != -1

    def startswith(self, other):
        return super(StringCompare, self).startswith(other)

    def endswith(self, other):
        return super(StringCompare, self).endswith(other)


print StringCompare('boogaloo').startswith('boo') # True
于 2012-04-14T19:45:27.253 に答える