質問

これは私がインターネットで見つけいくつかのコードです。私は、使用されることを意味しているかどうかはわかりません。私は単に列挙型のキー/値でのメンバーのを満たし、それが動作しますが、私はこのメタクラスはすべてに約あるか興味があります。私はそれがctypesのとは何かを持っていると仮定していますが、私はサブクラス化ctypesの上の多くの情報を見つけることができません。私はEnumerationTypeは何も私は列挙型を使用している方法をやっていません知っています。

from ctypes import *

class EnumerationType(type(c_uint)):  
    def __new__(metacls, name, bases, dict):  
        if not "_members_" in dict:  
            _members_ = {}  
            for key,value in dict.items():  
                if not key.startswith("_"):  
                    _members_[key] = value  
            dict["_members_"] = _members_  
        cls = type(c_uint).__new__(metacls, name, bases, dict)  
        for key,value in cls._members_.items():  
            globals()[key] = value  
        return cls  

    def __contains__(self, value):
        return value in self._members_.values()

    def __repr__(self):
        return "<Enumeration %s>" % self.__name__

class Enumeration(c_uint):
    __metaclass__ = EnumerationType
    _members_ = {}
    def __init__(self, value):
        for k,v in self._members_.items():
            if v == value:
                self.name = k
                break
        else:
            raise ValueError("No enumeration member with value %r" % value)
        c_uint.__init__(self, value)


    @classmethod
    def from_param(cls, param):
        if isinstance(param, Enumeration):
            if param.__class__ != cls:
                raise ValueError("Cannot mix enumeration members")
            else:
                return param
        else:
            return cls(param)

    def __repr__(self):
        return "<member %s=%d of %r>" % (self.name, self.value, self.__class__)

And an enumeration probably done the wrong way.  

class TOKEN(Enumeration):
    _members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}
役に立ちましたか?

解決

メタクラスはクラスを作成するために使用されるクラスです。それをこのように考える:すべてのオブジェクトは、クラスを持って、クラスもオブジェクトであるため、それはクラスがクラスを持つことができるという意味になります。

http://www.ibm.com/developerworks/linux /library/l-pymeta.htmlする

これがやっていることを理解するには、コード内のいくつかのポイントで見ることができます。

 _members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}

globals()[key] = value
「T_UNDEF」「T_NUMBERを」と、あなたのグローバル辞書でそれらが使用可能になります。

ここでは、辞書内のすべての定義されたキーになります。

def __init__(self, value):
    for k,v in self._members_.items():
        if v == value:
            self.name = k
            break

あなたが列挙型のインスタンスを作成するたびに、それはあなたがクラスを初期化するとき「の値が」許容列挙型名のリストにあるかどうかをチェックします。値が見つかった場合、それはself.nameに文字列名を設定します。

c_uint.__init__(self, value)

これは実際のCの符号なし整数に「ctypesの値」を設定実際の線である。

他のヒント

これは確かに奇妙なクラスです。

別の方法は次のようになりますが、

あなたがそれを使用している方法は、正しいです。

class TOKEN(Enumeration):
    T_UNDEF    = 0
    T_NAME     = 1
    T_NUMBER   = 2
    T_STRING   = 3
    T_OPERATOR = 4
    T_VARIABLE = 5
    T_FUNCTION = 6

(つまり__new__における最初の6行はのためにあるものです)

そして、あなたはそのようにそれを使用することができます:

>>> TOKEN
<Enumeration TOKEN>
>>> TOKEN(T_NAME)
<member T_NAME=1 of <Enumeration TOKEN>>
>>> T_NAME in TOKEN
True
>>> TOKEN(1).name
'T_NAME'

from_param方法は、intまたはEnumerationオブジェクトのいずれかを受け入れる方法を記述するため、便宜のためであると考えられます。それは本当に、その目的だ場合は本当にわからない。

私は、このクラスは外部APIを使用するCスタイルの列挙型で作業するときに使用されることを意図していると思うが、それは非常に少ない利益のために仕事の全体の多くのように見えます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top