ctypes إن شاء subclasses ترث - بيثون
سؤال
وهذه هي بعض الرموز وجدت على شبكة الانترنت. لست متأكدا كيف أنها تهدف لاستخدامها. أنا ببساطة ليس صحيحا <م> الأعضاء م> مع التعداد مفاتيح / القيم ويعمل، ولكن أنا الغريب ما هو هذا metaclass كل شيء. وأنا على افتراض أن لديها ما تفعله مع ctypes، ولكن لا أستطيع أن أجد الكثير من المعلومات عن ctypes إن شاء subclasses ترث. وأنا أعلم 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}
المحلول
وA metaclass هي فئة المستخدم في إنشاء فصول. التفكير في الأمر بهذه الطريقة: كل الأشياء لها فئة، فئة هو أيضا كائن، بالتالي، فمن المنطقي أن فئة يمكن أن يكون فئة
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" لج صحيحا غير موقعة الفعلي.
نصائح أخرى
وهذا هو في الواقع فئة غريبة.
والطريقة التي تستخدم بطريقة صحيحة، على الرغم من أن طريقة أخرى ستكون كما يلي:
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
يبدو أن للراحة، لكتابة الأساليب التي تقبل إما صحيح أو كائن Enumeration
. ليس متأكدا إذا كان هذا هو حقا الغرض منه.
وأعتقد أن المقصود هذه الفئة ليتم استخدامها عند التعامل مع واجهات برمجة التطبيقات الخارجية وتتضمن التعدادات استخدام أسلوب ج، ولكن يبدو أن مجموعة كبيرة من العمل لتحقيق مكاسب ضئيلة للغاية.