最新消息:20210917 已从crifan.com换到crifan.org

【部分解决】Python实现enum枚举的值是int整型和str字符串等复合类型的值

Python crifan 1031浏览 0评论
折腾:
【未解决】EvernoteToWordpress出错:TypeError string indices must be integers
期间,
想要去实现:enum中,定义name外,再定义字符串值和int值
class BaiduOcrApiErrorCode(enum):
    QPS_LIMIT_REACHED = 

'error_msg': 'image size error', 'error_code': 216202}

    RESP_ERR_CODE_ = 18
    RESP_ERR_TEXT_QPS_LIMIT_REACHED = "Open api qps request limit reached"

    RESP_ERR_CODE_DAILY_LIMIT_REACHED = 17
    RESP_ERR_TEXT_DAILY_LIMIT_REACHED = "Open api daily request limit reached"
之前记得弄过
去找找
python enum str int
python – Associating string representations with an Enum that uses integer values? – Stack Overflow
enum — Support for enumerations — Python 3.9.7 documentation
enum — 对枚举的支持 — Python 3.9.7 文档
python enum  value str and int
String-based enum in Python – Stack Overflow
python – enum – getting value of enum on string conversion – Stack Overflow
How to convert int to Enum in python? – Stack Overflow
Convert string to Enum in Python – Stack Overflow
python enum compound value
c# – Assign multiple values to enum elements – Stack Overflow
How can I represent an ‘Enum’ in Python? – Stack Overflow
python enum tuple
python tuple and enum – Stack Overflow
python enums with attributes – Stack Overflow
import enum
class EnumWithAttrs(enum.Enum):


    def __new__(cls, *args, **kwds):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj


    def __init__(self, a, b):
        self.a = a
        self.b = b


    GREEN = 'a', 'b'
    BLUE = 'c', 'd'
from enum import Enum


class Items(Enum):
    GREEN = ('a', 'b')
    BLUE = ('c', 'd')


    def __init__(self, a, b):
        self.a = a
        self.b = b
python – Getting enum object from string when enum values are tuples? – Stack Overflow
Python, what’s the Enum type good for? – Stack Overflow
enum — Support for enumerations — Python 3.9.7 documentation
enum — Support for enumerations — Python 3.9.7 documentation
>>> class Swatch(AutoNumber):
...     def __init__(self, pantone='unknown'):
...         self.pantone = pantone
...     AUBURN = '3497'
...     SEA_GREEN = '1246'
...     BLEACHED_CORAL = () # New color, no Pantone code yet!
...
>>> Swatch.SEA_GREEN
<Swatch.SEA_GREEN: 2>
>>> Swatch.SEA_GREEN.pantone
'1246'
>>> Swatch.BLEACHED_CORAL.pantone
'unknown'
去写代码试试
# import enum
from enum import Enum

class BaiduOcrApiError(Enum):
    """Baidu OCR API call response error
            错误码 - 文字识别OCR
            https://ai.baidu.com/ai-doc/OCR/dk3h7y5vr
    """


    def __init__(self, errCode=1, errMsg="Unknown error"):
        self.errCode = errCode
        self.errMsg = errMsg


    DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
    QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
    IMAGE_SIZE_ERROR = (216202, "image size error")


        if "error_code" in respJson:
            logging.warning("respJson=%s", respJson)
            errorCode = respJson["error_code"]
            errorMsg = respJson["error_msg"]


            respErrEnum = BaiduOcrApiError(errCode=errorCode, errMsg=errorMsg)
            logging.warning("respErrEnum=%s", respErrEnum)


            # 【已解决】Linux或Mac的终端中如何显示带颜色的文字即彩色文字
            # 20210924 12:06:50 crifanEvernote.py:750  INFO    [1/60] imgFilename=None
            # 20210924 12:06:50 crifanEvernote.py:717  INFO    Resized: PNG,12x12,157.0B -> PNG,12x12,157.0B => ratio=100%
            # ->
            # respJson={'log_id': 1441252773455773889, 'error_msg': 'image size error', 'error_code': 216202}


            # {'error_code': 17, 'error_msg': 'Open api daily request limit reached'}
            # {'error_code': 18, 'error_msg': 'Open api qps request limit reached'}
            # the limit count can found from
            # 文字识别 - 免费额度 | 百度AI开放平台
            # https://ai.baidu.com/ai-doc/OCR/fk3h7xu7h
            # for "通用文字识别(高精度含位置版)" is "50次/天"
            if respErrEnum == BaiduOcrApiError.QPS_LIMIT_REACHED:
                # wait sometime and try again
                time.sleep(1.0)
                resp = requests.post(self.OCR_URL, params=paramDict, headers=headerDict, data=dataDict)
                respJson = resp.json()
                logging.debug("baidu OCR: for errorCode=%s, do again, imgage=%s -> respJson=%s", errorCode, imagePath, respJson)
            elif respErrEnum == BaiduOcrApiError.DAILY_LIMIT_REACHED:
                logging.error("Fail to continue using baidu OCR api today for exceed free limit of single day !!!")
                respJson = None
            else:
                logging.error("For other baidu OCR api error %s, just set to None", respErrEnum)
                respJson = None
去调试看看
会报错:
Exception has occurred: TypeError
__call__() got an unexpected keyword argument 'errCode'
File "/Users/crifan/dev/dev_root/crifan/EvernoteToWordpress/EvernoteToWordpress/libs/crifan/baiduOcr.py", line 168, in imageToWords respErrEnum = BaiduOcrApiError(errCode=errorCode, errMsg=errorMsg)
enum — Support for enumerations — Python 3.9.7 documentation
说是:要集成AutoNumber
-》自动赋给number=数字的值:从1到N
其他额外的值,可以自己赋值
但是此处,自己是 要赋值2个,一个是int,一个是str
好像必须集成一种?
比如IntEnum?
刚注意到,前面例子:
from enum import Enum

class Items(Enum):
    GREEN = ('a', 'b')
    BLUE = ('c', 'd')

    def __init__(self, a, b):
        self.a = a
        self.b = b
中,都是str值
那去试试AutoNumber
发现要额外定义AutoNumber
算了。
搜搜看
EnumWithAttrs
python EnumWithAttrs
没有
python Enum With Attrs
python enums with attributes – Stack Overflow
import enum
class EnumWithAttrs(enum.Enum):

    def __new__(cls, *args, **kwds):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

    def __init__(self, a, b):
        self.a = a
        self.b = b

    GREEN = 'a', 'b'
    BLUE = 'c', 'd'
原来是:EnumWithAttrs是自定义类的名字。。。
试试:
# class BaiduOcrApiError(AutoNumber):
class BaiduOcrApiError(Enum):
    """Baidu OCR API call response error
            错误码 - 文字识别OCR
            https://ai.baidu.com/ai-doc/OCR/dk3h7y5vr
    """


    def __new__(cls, *args, **kwds):
            value = len(cls.__members__) + 1
            obj = object.__new__(cls)
            obj._value_ = value
            return obj


    # def __init__(self, errCode=1, errMsg="Unknown error"):
    def __init__(self, errCode=1, errMsg="Unknown error"):
        self.errCode = errCode
        self.errMsg = errMsg


    DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
    QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
    IMAGE_SIZE_ERROR = (216202, "image size error")
结果:
调试,初始化后:
第一个enum变量初始化
看起来没问题。
然后
第二次运行了:__new__
value=2
问题依旧:
Exception has occurred: TypeError
__call__() got an unexpected keyword argument 'errCode'
突然想到,先去试试:
respErrEnum = BaiduOcrApiError(errorCode, errorMsg)
结果:
报错:
Exception has occurred: TypeError
Cannot extend enumerations
去试试:
from collections import namedtuple
from enum import Enum


class Status(namedtuple('Status', 'name description'), Enum):
    READY = 'ready', 'I am ready to do whatever is needed'
    ERROR = 'error', 'Something went wrong here'


    def __str__(self) -> str:
        return self.name
的:

from collections import namedtuple
from enum import Enum


class BaiduOcrApiError(namedtuple("errCode", "errMsg"), Enum):
    """Baidu OCR API call response error
            错误码 - 文字识别OCR
            https://ai.baidu.com/ai-doc/OCR/dk3h7y5vr
    """


    # def __new__(cls, *args, **kwds):
    #         value = len(cls.__members__) + 1
    #         obj = object.__new__(cls)
    #         obj._value_ = value
    #         return obj


    # # def __init__(self, errCode=1, errMsg="Unknown error"):
    # def __init__(self, errCode=1, errMsg="Unknown error"):
    #     self.errCode = errCode
    #     self.errMsg = errMsg


    def __new__(cls, errCode=1, errMsg="Unknown error"):
            value = len(cls.__members__) + 1
            obj = object.__new__(cls)
            obj._value_ = value


            obj.errCode = errCode
            obj.errMsg = errMsg


            return obj


    DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
    QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
    IMAGE_SIZE_ERROR = (216202, "image size error")
结果:
Exception has occurred: TypeError

object.__new__(BaiduOcrApiError) is not safe, use tuple.__new__()

File "/Users/crifan/dev/dev_root/crifan/EvernoteToWordpress/EvernoteToWordpress/libs/crifan/baiduOcr.py", line 67, in __new__ obj = object.__new__(cls)
改为:
            # obj = object.__new__(cls)
            obj = tuple.__new__(cls)
报错:
Exception has occurred: AttributeError
can't set attribute
File "/Users/crifan/dev/dev_root/crifan/EvernoteToWordpress/EvernoteToWordpress/libs/crifan/baiduOcr.py", line 72, in __new__ obj.errMsg = errMsg File
感觉是:
errMsg是内置的属性,不能用。
看来是:
Python内置变量属性,是蓝色的。
-》蓝色的,是内置属性
-》自己不能用
估计改个名字即可
    def __new__(cls, errorCode=1, errorMsg="Unknown error"):
            value = len(cls.__members__) + 1
            # obj = object.__new__(cls)
            obj = tuple.__new__(cls)
            obj._value_ = value


            obj.errorCode = errorCode
            obj.errorMsg = errorMsg


            return obj
结果:
可以设置值,但是:
没有新增自定义属性errorCode和errorMsg
respErrEnum = BaiduOcrApiError(errorCode, errorMsg)
依旧报错:
Exception has occurred: TypeError
Cannot extend enumerations
那去想办法,传入named tuple
python named tuple
What are “named tuples” in Python? – Stack Overflow
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)


import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"])   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1
去试试
            RespError = namedtuple("RespError", "errorCode errorMsg")
            curRespError = RespError(errorCode, errorMsg)
            respErrEnum = BaiduOcrApiError(curRespError)
结果:
Exception has occurred: ValueError
RespError(errorCode=216202, errorMsg='image size error') is not a valid BaiduOcrApiError
File "/Users/crifan/dev/dev_root/crifan/EvernoteToWordpress/EvernoteToWordpress/libs/crifan/baiduOcr.py", line 194, in imageToWords respErrEnum = BaiduOcrApiError(curRespError)
试试:
class BaiduOcrApiError(tuple, Enum):

    def __new__(cls, errorCode=1, errorMsg="Unknown error"):
            # value = len(cls.__members__) + 1
            # obj = object.__new__(cls)
            obj = tuple.__new__(cls)
            obj._value_ = errorCode


            # obj.errorCode = errorCode
            obj.errorMsg = errorMsg


            return obj
调用:
            respErrTuple = (errorCode, errorMsg)
            respErrEnum = BaiduOcrApiError(respErrTuple)
结果:
Exception has occurred: TypeError
not enough arguments for format string
用:
  respErrEnum = BaiduOcrApiError(errorCode, errorMsg)
结果:
Exception has occurred: TypeError
Cannot extend enumerations
Python enum init tuple Cannot extend enumerations
enum — Support for enumerations — Python 3.9.7 documentation
python enum value returns tuple
python enums with attributes – Stack Overflow
python create tuple enum
python initialize tuple enum
python  enum int and string
How to use strings as name aliases in Python enums – Not Invented Here
Associating string representations with an Enum that uses integer values? | Newbedev
先试试:
respErrEnum = BaiduOcrApiError((errorCode, errorMsg))
结果:
Exception has occurred: ValueError
(216202, 'image size error') is not a valid BaiduOcrApiError
那试试:
直接新建一个空的,然后再去赋值
  respErrEnum = BaiduOcrApiError()
  respErrEnum.errCode = errorCode
  respErrEnum.errMsg = errorMsg
结果:
报错:
Exception has occurred: TypeError
__call__() missing 1 required positional argument: 'value'
File "/Users/crifan/dev/dev_root/crifan/EvernoteToWordpress/EvernoteToWordpress/debug/baiduOcr/debugErrorEnum.py", line 55, in <module> respErrEnum = BaiduOcrApiError()
试试:
respErrEnum = BaiduOcrApiError(value=(errorCode, errorMsg))
结果:
Exception has occurred: ValueError
(216202, 'image size error') is not a valid BaiduOcrApiError
去安装aenum试试
pip install aenum
pipenv install aenum
结果:
from aenum import AutoNumberEnum

class BaiduOcrApiError(AutoNumberEnum):
  _init_ = "errorCode errorMsg"

  DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
  QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
  IMAGE_SIZE_ERROR = (216202, "image size error")


if __name__ == "__main__":
  errorCode = 216202
  errorMsg = 'image size error'
  respErrEnum = BaiduOcrApiError(errorCode, errorMsg)
结果:
Exception has occurred: TypeError
cannot extend enumerations via subclassing
respErrEnum = BaiduOcrApiError((errorCode, errorMsg))
结果:
Exception has occurred: ValueError
(216202, 'image size error') is not a valid BaiduOcrApiError
python  enum dynamic
Dynamically create an enum with custom values in Python? – Stack Overflow
dynamic – Adding members to Python Enums – Stack Overflow
”extend_enum in action:
from aenum import extend_enum
extend_enum(Color, ‘white’, 1)
print Color, list(Color)
print repr(Color.black), Color.black, repr(Color.white), Color.white
去试试
也不对,此处是:
对enum进行扩展
此处不是想要扩展,而是想要:
判断当前的值,是否在enum中
但是此处,暂时的需求是:
只需要得知errorCode,即可够用,去判断此处的是否是其中2种,如果不是,else处理即可
另外,此处调试发现:
from enum import Enum

class BaiduOcrApiError(tuple, Enum):
    def __new__(cls, errorCode=1, errorMsg="Unknown error"):
            # value = len(cls.__members__) + 1
            # obj = object.__new__(cls)
            obj = tuple.__new__(cls)
            obj._value_ = errorCode


            obj.errorCode = errorCode
            obj.errorMsg = errorMsg


            return obj

    DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
    QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
    IMAGE_SIZE_ERROR = (216202, "image size error")
竟然是:
即:
  • errorCode = 17, “Open api daily request limit reached”
  • errorMsg = (默认的)”Unknown error”
而不是以为的:
  • errorCode=17
  • errorMsg = “Open api daily request limit reached”
改为:
  DAILY_LIMIT_REACHED = 17, "Open api daily request limit reached"
  QPS_LIMIT_REACHED = 18, "Open api qps request limit reached"
  IMAGE_SIZE_ERROR = 216202, "image size error"
结果:
问题依旧。
改为:
  # def __new__(cls, errorCode=1, errorMsg="Unknown error"):
  def __new__(cls, errTuple=(1, "Unknown error")):
    errorCode = errTuple[0]
    errorMsg = errTuple[1]


    # value = len(cls.__members__) + 1
    # obj = object.__new__(cls)
    obj = tuple.__new__(cls)
    obj._value_ = errorCode


    obj.errorCode = errorCode
    obj.errorMsg = errorMsg


    return obj
结果:
输入的值是对的,tuple
也还是只有value属性
没有自己加的
errorCode
errorMsg
问题依旧:
Exception has occurred: ValueError
(216202, 'image size error') is not a valid BaiduOcrApiError
目前没法完全实现需求:
(1)定义一个enum,name的value是tuple的int和string
(2)然后从int和string,去动态创建enum
目前只能实现前者:
(1)定义一个enum,name的value是tuple的int和string
代码:
from enum import Enum

class BaiduOcrApiError(tuple, Enum):

        errorCode = errTuple[0]
        errorMsg = errTuple[1]

        # value = len(cls.__members__) + 1
        # obj = object.__new__(cls)
        obj = tuple.__new__(cls)
        obj._value_ = errorCode

        obj.errorCode = errorCode
        obj.errorMsg = errorMsg

        return obj

    DAILY_LIMIT_REACHED = (17, "Open api daily request limit reached")
    QPS_LIMIT_REACHED = (18, "Open api qps request limit reached")
    IMAGE_SIZE_ERROR = (216202, "image size error")
调用:
            if errorCode == BaiduOcrApiError.QPS_LIMIT_REACHED.errorCode:
无法实现:
(2)然后从int和string,去动态创建enum

转载请注明:在路上 » 【部分解决】Python实现enum枚举的值是int整型和str字符串等复合类型的值

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
79 queries in 0.115 seconds, using 21.33MB memory