2017-12-28 6 views
2

私はPythonのメタクラスに新しいですが、次のコード実行している: - my_decoratorはメタクラスを使用して、クラス内の属性へのアクセス - Pythonの

class A(type): 

     @classmethod 
     def _handle_attrs(cls, class_name, bases, attrs, **kwargs): 

      # Now lets find all handlers defined for this class 
      current_attr = [(att, getattr(attrs[att], "__my_attr")) for att in attrs if 
          hasattr(attrs[att], '__my_attr')] 

      print hasattr(attrs, '__my_attr') # returns False 

     def __new__(cls, class_name, bases, attrs, **kwargs): 
      cls._handle_attrs(class_name, bases, attrs, **kwargs) 
      return type.__new__(cls, class_name, bases, attrs, **kwargs) 


    # adding the decorators args as a class attribute 

    def my_decorator(*args, **kwargs): 
     def _my_decorator(cls): 
      if hasattr(cls, '__my_attr'): 
       cls.__my_attr.update(kwargs) 
      else: 
       cls.__my_attr = kwargs 
      return cls 
     return _my_decorator 

    class B: 
     __metaclass__ = A 

     def get_attr_dict(self): 
      return getattr(self, '__my_attr', None) 


    @my_decorator(w = 'W') 
    @my_decorator(z = 'Z') 
    class C(B): 
     x = 'X' 
     y = 'Y' 

    test = C() 

    print test.__class__.__dict__ 
    print test.__my_attr # this returns {'w': 'W', 'z': 'Z'} 

を私はクラスは、クラスのデコレータを使用してCクラスに属性を追加しています。 _handle_attrs関数では、追加された属性に対して何かしたいと思います。

問題が追加された属性が下に追加されていることである。test._ _class __._ _dict__とメタクラスでCを作成するときに、私はそれらにアクセスする方法がわからない...

+0

Pythonは実行して探索する素晴らしい言語です。メタクラスは多くの可能性を提供しますが、最近はPython 3でこれを行うべきです。 Python 2.7は10年近く経っており、多くの新機能が欠けています。 – jsbueno

+0

別のこと:あなたのプライベート属性の接頭辞として二重のアンダースコアを使用しないでください。それはあなたの実験で問題になるだけです。 Pythonには**プライベート属性がありません。ダブルアンダースコアは_compile time_ nameマングルを引き起こし、コードエラーを起こしやすくなり、デバッグが非常に難しくなります。 **慣例**は、プライベートアトリビュートに使用される接頭辞が単一のアンダースコアであることです。 – jsbueno

答えて

2

メタクラス__new__されますそれを使用するクラスの定義を実行します。

@my_decorator(w = 'W', z = 'Z') 
class C(B): 
    x = 'X' 
    y = 'Y' 

ので、メタクラスは、すでにあなたのデコレータは、その属性を追加し、時間によって、その仕事をしたことは明らかである

class C(B): 
    x = 'X' 
    y = 'Y' 

C = my_decorator(w = 'W', z = 'Z')(C) 

に相当します。

+0

メタクラスが実行される前にデコレータから属性を追加する方法はありますか? –

+0

クラスデコレータではありません。 – schwobaseggl

関連する問題