首页 > 解决方案 > Set attribue in custom class derived from uuid.UUID: AttributeError

问题描述

I'm porting some code from IronPython to CPython (3.8) + Python.NET and I have a custom class that's broken in an odd way: it gives me an AttributeError even though the member is present in __dict__. This class derives from uuid.UUID to add support to BLE short UUIDs:

import uuid

class UUID(uuid.UUID):
    """Represents a more general version of the uuid.UUID, so we can have both
            regular and short UUIDs.
    """

    def __init__(self, hex=None, bytes=None, is_short=False, **kwargs):
        try:
            super(UUID, self).__init__(hex=hex, bytes=bytes, **kwargs)
            self.__dict__['is_short'] = False
        except ValueError as val_ex:
            if hex is None or len(hex) != 4:
                raise val_ex

            # Remove braces GUIDs 
            hex_digits = hex.strip('{}').replace('-', '')

            # remove RFC 4122 URN's 'urn:uuid:deadbeef-1234-fedc-5678-deadbeefaaaa'
            hex_digits = hex_digits.replace('uuid:', '').replace('urn:', '')

            if len(hex_digits) != 4:
                raise ValueError('badly formed hexadecimal UUID string')
            self.__dict__['int'] = int(hex, 16)
            self.__dict__['is_short'] = True

        if is_short is True:
            self.__dict__['is_short'] = True

    def __str__(self):
        if self.is_short:
            hex = '%04x' % self.int
            return '%s' % (hex[:4])
        else:
            return super(UUID, self).__str__()

And I'm using it like so:

class Test_UUID(unittest.TestCase):
    def test_create(self):
        x = pybletestlibrary.UUID("1800")
        pprint(x.__dict__)
        print(x)

The above code yields:

{'int': 6144, 'is_short': True}
E
======================================================================
ERROR: test_create (__main__.Test_UUID)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test\test_pybletestlibrary.py", line 27, in test_create
    print(x)
  File "my_uuid.py", line 66, in __str__
    hex = '%04x' % self.int
AttributeError: int
----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (errors=1)

I can't use setattr() because uuid.UUID is immutable. I don't understand why the AttributeError as int is present in __dict__. Any suggestions?

Thanks!!

标签: pythonbluetooth-lowenergyuuid

解决方案


这就是我的意思:

import uuid

class UUID(uuid.UUID):
    """Represents a more general version of the uuid.UUID, so we can have both
            regular and short UUIDs.
    """

    def __init__(self, hex=None, bytes=None, is_short=False, **kwargs):
        self.is_short = False
        if len(hex) == 4:
            self.is_short = True
            hex = "0000"+hex+"-0000-1000-8000-00805f9b34fb"
        super(UUID, self).__init__(hex=hex, bytes=bytes, **kwargs)

    def __str__(self):
        val = super(UUID, self).__str__()
        if self.is_short:
            return val[4:8]
        else:
            return val

您可能还必须覆盖其他一些属性。


推荐阅读