Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonのメタクラスを使用したメタプログラミング


メタプログラミングという用語は、コンピュータープログラムがそれ自体を操作したり、知識を持ったりしようとするコンピュータープログラミングを指します。 Pythonは、メタクラスと呼ばれる新しいタイプのクラスを介したクラスのメタプログラミングをサポートしています。

Pythonのメタクラスを介したメタプログラミングは、既存のコードを変更、ラップ、または生成することによってコードを操作する関数とクラスを構築することです。

メタプログラミングの主な機能は次のとおりです-

  • メタクラス
  • デコレータ
  • クラスデコレータ

メタクラスとは

メタクラスの非常に限定された定義は、クラスを作成するクラスである可能性があります。 Pythonはオブジェクト指向言語であり、すべてがオブジェクトであり、クラスも例外ではありません。 classキーワードでクラスを定義すると、Pythonは実際にそれを実行してから、オブジェクトを生成します。オブジェクトであるため、関数パラメータとして、属性の割り当て、コピー、追加などを行うことができます。メタクラスを使用すると、クラスのプロパティの変更、プロパティの正当性の確認など、クラスの生成を制御できます。

Python組み込みメタクラス

すべてのクラスのメタクラスはタイプです

class a:
pass

print(type(a))

出力:

<class 'type'>

上記の出力から、「a」(クラス)がクラス型のオブジェクトであることがわかります。 「a」(クラス)はクラス型のインスタンスであるとも言えます。したがって、typeはメタクラスです。したがって、Pythonでは、すべてのクラスが組み込みのメタクラスタイプに属します。

Pythonのメタクラスを使用したメタプログラミング

メタクラスを使用してPythonクラスを作成する

上記の例で見たように、タイプはデフォルトのメタクラスです。このデフォルトのmetaclass(type)を使用して、新しいクラスを作成できます。

>>> class hello(object):
pass

この方法でも手動で作成できます-

>>> hello = type('hello', (), {})
>>> print(hello)# returns a class object

>>> print(hello()) # creates an instance with the class
<__main__.hello object at 0x05D86830>

タイプはクラスの属性を定義する辞書を受け入れるので、

>>> class hello(object):
   world = True

上記のコードは、

に似ています
hello = type('hello', (), {'world' : True})

メタクラスを作成する

では、いつメタクラスを作成するのでしょうか?クラスのプロパティの確認や変更など、クラスの作成を制御したい場合。

クラスのインスタンス化プロセス-

  • __ new __()を呼び出してインスタンスを作成します
  • __ init __()を呼び出して、上記で作成したインスタンスを初期化します

したがって、カスタムメタクラスを作成するときは、実際には親クラスの__new __()または__init__メソッドを変更します。

例1-クラスのプロパティを変更したメタクラス
class LowercaseMeta(type):
   def __new__(mcs, name, bases, attrs):
      lower_attrs = {}
      for k, v in attrs.items():
         if not k.startswith('__'):
            lower_attrs[k.lower()] = v
         else:
            lower_attrs[k] = v
      return type.__new__(mcs, name, bases, lower_attrs)
class LowercaseClass(metaclass=LowercaseMeta):
   BAR = True
   def HELLO(self):
      print('hello')

print(dir(LowercaseClass))
LowercaseClass().hello()

出力

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'hello']
hello
例2-クラスに属性を追加します
class ListMeta(type):
   def __new__(mcs, name, bases, attrs):
      attrs['add'] = lambda self, value: self.append(value)
      return type.__new__(mcs, name, bases, attrs)
class MyList(list, metaclass=ListMeta):
pass
l = MyList()
l.add(1)
print(l)
def class_decorator(cls):
   cls.add = lambda self, value: self.append(value)
   return cls

@class_decorator
class MyList(list):
   pass
l = MyList()
l.append(1)
print(l)

出力

[1]
[1]

__metaclass__属性

Pythonでは、クラスがあるか、そのベースの1つに__metaclass__属性があり、メタクラスと見なされます。それ以外の場合、タイプはメタクラスです。クラスを-

と書くと、__metaclass__属性を持つことができます。

つまり、-

のようなクラスを定義するとどうなるでしょうか。
class hello(object):
   x = 10

上記では、helloクラスには__metaclass__属性がないため、代わりにタイプが使用され、クラスの作成は-

として実行されます。
hello = type(name, bases, dict)

helloにメタクラスが定義されている場合-

class hello(object):
__metaclass__ = myMetaClass
pass

上記の例では、クラスの作成はtypeではなくmyMetaClassを使用して行われます。こんにちは=myMetaClass(name、bases、dict)


  1. Pythonでの継承

    この記事では、Python3.xでの継承と拡張クラスについて学習します。またはそれ以前。 継承は実際の関係をうまく表し、再利用性を提供し、推移性をサポートします。開発時間が短縮され、メンテナンスが容易になり、拡張も容易になります。 継承は大きく5つのタイプに分類されます- シングル 複数 階層的 マルチレベル ハイブリッド 上の図に示されているように、継承とは、実際に親クラスのオブジェクトを作成せずに、他のクラスの機能にアクセスしようとするプロセスです。 ここでは、単一の階層型継承の実装について学習します。 単一継承 例 # parent class class Studen

  2. Pythonでのタートルプログラミング

    カメはPythonの特別な羽です。 Turtleを使用すると、簡単に製図板に描くことができます。 まず、タートルモジュールをインポートします。次にウィンドウを作成し、次にタートルオブジェクトを作成し、タートルメソッドを使用して製図板に描画できます。 いくつかのカメの方法 方法 パラメータ 説明 Turtle() なし 新しいタートルオブジェクトを作成して返します forward() 金額 指定された量だけカメを前進させます backward() 金額 指定された量だけカメを後方に動かします right() 角度 カメを時計回りに回転させます left() 角