문제
이것은 인터넷에서 찾은 코드입니다. 그것이 어떻게 사용되어야하는지 잘 모르겠습니다. 나는 단순히 채웠다 회원 열거 키/값과 작동하지만이 메타 클래스가 무엇인지 궁금합니다. 나는 그것이 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 스타일 열거 사용을 사용하는 것은 거의 이득이 거의없는 많은 작업처럼 보입니다.