如何创建类型“等于”int的类?

2024-09-30 14:25:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个数据类,它可以从类型定义生成clickhouse(SQLISH)模式

例如,clickhouse支持:

  • Int8
  • Int16
  • Uint8
  • Uint16

在python中,这些类型不存在(afaik)。只是int。我希望我仍然可以创建一个类型结构,让我来表达它,并自动生成所需的模式,也许还可以对类型进行验证。我还希望当我传递int类型的值时,我的类型提示(我使用PyCharm,不确定mypy)不会抱怨

到目前为止,这是我的想法:

@dataclass
class ClickhouseType:
    @classmethod
    def schema_type(cls):
        return cls.__name__

    @classmethod
    def validate(cls, value):
        # just included as an example, not important as part of this discussion :) 
        pass


@dataclass
class Int8(int, ClickhouseType):
    @classmethod
    def validate(cls, value):
        # just included as an example, not important as part of this discussion :)
        assert -128 <= value <= 127

@dataclass
class MySchema:
    some_number: Int8


x = MySchema(some_number=4)  # type hint complaints that I pass an int when an Int8 is required

有没有办法让python/my-type-hinter明白我希望Int8可以与int互换


Tags: an类型valuedefastype模式class
1条回答
网友
1楼 · 发布于 2024-09-30 14:25:01

尝试使用直接继承创建类型:

class int8 (int):
    def __new__ (cls, value):
        assert -128<=value<=127
        return int(value) # Simplified
        # Or if you need more things:
        self = int.__new__(cls, value)
        self.something = "something else"
        return self

根据shadowranger的评论提示进行编辑:

Everything here will be type(int(...))==type(int8(...))==True, except the classes
__name__ attribute after instancing. And int8().__class__ of course.
Remember that the __new__() constructor is called before anything else in the class is "considered objectified". Therefore before the __init__() as well. __init__() is called after the object's construction, while __new__() is called practically before it.
__new() receives the class as a first argument, while __init__() receives already constructed object.
So, if multiple inheritance is used, some of initialization should go to __new__(), mostly those modifying the data type, and some of it should be done in __init__().

Note that type(int)!=type(int8)==True here, so this is not really an exact answer to your question, but it should be a good pointer combined with what you already know.

相关问题 更多 >