PEP 3115で説明されている「順序付きクラス」 (つまり、メンバーが宣言された順序でアクセスできるクラス)を使用しようとしています。そこに与えられた実装は
# The custom dictionary
class member_table(dict):
def __init__(self):
self.member_names = []
def __setitem__(self, key, value):
# if the key is not already defined, add to the
# list of keys.
if key not in self:
self.member_names.append(key)
# Call superclass
dict.__setitem__(self, key, value)
# The metaclass
class OrderedClass(type):
# The prepare function
@classmethod
def __prepare__(metacls, name, bases): # No keywords in this case
return member_table()
# The metaclass invocation
def __new__(cls, name, bases, classdict):
# Note that we replace the classdict with a regular
# dict before passing it to the superclass, so that we
# don't continue to record member names after the class
# has been created.
result = type.__new__(cls, name, bases, dict(classdict))
result.member_names = classdict.member_names
return result
class MyClass(metaclass=OrderedClass):
# method1 goes in array element 0
def method1(self):
pass
# method2 goes in array element 1
def method2(self):
pass
私が混乱していることがいくつかあります。まず、 である理由__prepare__
はありclassmethod
ますか?定義は使用しませんmetacls
-これは単なる慣習ですか?
第二に、このコードを試してみると'__module__'
、MyClass.member_names
最初'method1'
の要素'method2'
であると主張するコメントと矛盾しているように見えます。'method1'
この特別な属性がリストに含まれるのに、他の属性が含まれないのはなぜですか? 私を驚かせる可能性のあるものは他にありますか (__doc__
クラスに docstring があり、明示的に定義したものを除く)?
member_names
最後に、この実装は基本クラスから を取得しません。それを達成したい場合、次の変更に何か問題がありますか__prepare__
(重複をチェックしないという事実を除いて)?
@classmethod
def __prepare__(metacls, name, bases):
prep_dict = member_table()
for base in bases:
try:
prep_dict.member_names.extend(base.member_names)
except AttributeError:
pass
return prep_dict