0

私はPythonでメタプログラミングを始めました。次のようなことをしたいと思います。metaclassing fromkeysとStructを使ったOrderdDict

from struct import Struct, error as StructError 
from collections import OrderedDict 
from typing import List, Hashable 
from uuid import UUID 

class StructBytes(type): 

    def __prepare__(name, bases, **kwds): 
     return OrderedDict() 

    # return a subclass/modification of OrdereDict with predefined keys and a Struct(fmt) 
    # __init__ should fill key values from Struct.unpack(bytes) 
    # in principle (although not necessary), this is a frozen ordered dict 

... 

class ThisFormat(metaclass=StructBytes, keys: List[Hashable], fmt: str) 

    def __init__(some_bytes: bytes) 
     try: 
      # call to __init__ should use specified formatting 
     except StructError: 
      # some_bytes not valid for this class 
     else: 
      # do post-processing on some field values, like: 
      self['uuid'] = UUID(bytes=self['uuid']) 

for some_bytes in buffer: 
    structured = ThisFormat(some_bytes) 
    structured[field] # returns post-processed bytes 

しかし、この時点では実装方法はわかりません。私がメタプログラミングのために見る理由は、ThisFormatの複数のバージョンが、それぞれ特定のフィールドキーとバイト構造(すなわち、Structのためのフォーマット)で存在することです。誰かが私にいくつかのポインタを与えることができますか?

答えて

0

は、(例の)より簡単な解決策を見つけた:

from struct import Struct, error as StructError 
from collections import OrderedDict 
from typing import * 


class StructBytes(Mapping[Hashable, Any]): 
    __fields__: List[Hashable] 
    __struct__: Struct 

    def __init__(self, bytestring: bytes): 
     try: 
      values = self.__struct__.unpack(bytestring) 
     except StructError as e: 
      raise ValueError("invalid bytestring for formatting") from e 
     else: 
      self.__dict__ = OrderedDict(zip(self.__fields__, values)) 
      for f in self.__fields__: 
       if f not in self: 
        raise KeyError("failed to retrieve field '{}'".format(f)) 

    def __getitem__(self, key) -> Any: 
     return self.__dict__[key] 

    def __iter__(self) -> Iterator: 
     return iter(self.__dict__) 

    def __len__(self) -> int: 
     return len(self.__dict__) 

    def __repr__(self) -> str: 
     return repr(self.__dict__) 

    def keys(self) -> KeysView: 
     return self.__dict__.keys() 

    def values(self) -> ValuesView: 
     return self.__dict__.values() 

    def items(self) -> ItemsView: 
     return self.__dict__.items() 


class UART(StructBytes): 
    __fields__ = ['header length', 'payload length', 'protocol version', 
        'packet count', 'packet id'] 
    __struct__ = Struct("<BBBHB") 

    def __init__(self, bytestring: bytes): 
     super(UART, self).__init__(bytestring) 
     if self['packet id'] == 0x06: 
      self.__dict__['packet id'] = "EVENT_PACKET" 
     else: 
      raise NotImplementedError("undefined packet type") 


uart = (
    b'\x06' # header length 
    b'\x38' # payload length 
    b'\x01' # version 
    b'\x8D\x97' # packet counter 
    b'\x06' # packet id 
) 
test = UART(uart) 
関連する問題