サブクラスの本体から親クラスの属性にアクセスする 質問する

サブクラスの本体から親クラスの属性にアクセスする 質問する

Klassクラス属性を持つクラスがありますmy_list。そのサブクラスがあり、その中に親クラスの同じ属性の修正バージョンであるSubKlassクラス属性を持たせたいと考えています。my_list

class Klass():
    my_list = [1, 2, 3]


class SubKlass(Klass):
    my_list = Klass.my_list + [4, 5] # this works, but i must specify parent class explicitly
    #my_list = super().my_list + [4, 5] # SystemError: super(): __class__ cell not found
    #my_list = my_list + [4, 5] # NameError: name 'my_list' is not defined 


print(Klass.my_list)
print(SubKlass.my_list)

では、名前を指定せずに親クラス属性にアクセスする方法はあるのでしょうか?

アップデート:

Python の問題追跡にバグがあります:翻訳: 翻訳者: pythonそうなることを祈りましょう解決済みある時点で。

ベストアンサー1

あなたはできません。

Python でのクラス定義は次のように機能します。

  1. インタープリターは、classステートメントの後にコード ブロックが続くのを確認します。

  2. 新しい名前空間を作成し、その名前空間内でそのコードを実行します。

  3. type結果の名前空間、クラス名、基本クラス、およびメタクラス (該当する場合) を使用して組み込みを呼び出します。

  4. 結果をクラスの名前に割り当てます。

クラス定義内でコードを実行している間は、基本クラスが何であるかわからないため、その属性を取得できません。

あなたができるクラスを定義した直後にクラスを変更します。


編集: 属性を更新するために使用できる小さなクラス デコレータがあります。アイデアは、名前と関数を指定することです。クラスのすべての基本クラスを調べて、その名前の属性を取得します。次に、基本クラスから継承した値のリストとサブクラスで定義した値を使用して関数を呼び出します。この呼び出しの結果は、名前にバインドされます。

コードの方が意味をなすかもしれません:

>>> def inherit_attribute(name, f):
...     def decorator(cls):
...             old_value = getattr(cls, name)
...             new_value = f([getattr(base, name) for base in cls.__bases__], old_value)
...             setattr(cls, name, new_value)
...             return cls
...     return decorator
... 
>>> def update_x(base_values, my_value):
...    return sum(base_values + [my_value], tuple())
... 
>>> class Foo: x = (1,)
... 
>>> @inherit_attribute('x', update_x)
... class Bar(Foo): x = (2,)
... 
>>> Bar.x
(1, 2)

アイデアとしては、 を で定義することですx(2,)デコレータBarは のサブクラスを調べてBar、その をすべて見つけxupdate_xそれらを使って を呼び出します。つまり、

update_x([(1,)], (2,))

これらを連結して結合し、それを再びバインドしますx。意味がわかりますか?

おすすめ記事