문제

이것은 인터넷에서 찾은 코드입니다. 그것이 어떻게 사용되어야하는지 잘 모르겠습니다. 나는 단순히 채웠다 회원 열거 키/값과 작동하지만이 메타 클래스가 무엇인지 궁금합니다. 나는 그것이 CTypes와 관련이 있다고 가정하지만 서브 클래스 CTYPES에 대한 많은 정보를 찾을 수 없습니다. 나는 열거형 유형이 열거를 사용하는 방식으로 아무것도하지 않는다는 것을 알고 있습니다.

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)

이것은 "CTypes 값"을 실제 C 부호없는 정수로 설정하는 실제 선입니다.

다른 팁

그것은 실제로 이상한 수업입니다.

다른 방법은 다음과 같습니다. 또 다른 방법은 다음과 같습니다.

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

(그게 처음 6 줄입니다 __new__ )

그런 다음 그렇게 사용할 수 있습니다.

>>> 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