如何使类的字段与构造函数中的参数具有相同的类型

脑部服务

我是一个完全“静态类型”的人,并且是python的初学者,我想在python中创建数据类型,以保存某些对象的上一个-下一个状态。结构是这样的:

class PrevCurr:
    def __init__(self, obj_initial):
       self.previous = obj_initial
       self.current = obj_initial

没问题,如果我obj_initial[None, None]这样的。但是想象一下,我需要将该类包装到不同的大类型上,例如1000种以上的字典/列表/集合或/和用户定义的类。然后,我想要这样的东西:

class PrevCurr:
    def __init__(self, obj_type, *args, **kwargs):
       '''make self.previous and self.orientation of the same type as obj_type'''
       self.previous = ...
       self.current = ...

我的问题是:如何确定将字段(或python中是否有其他名称?)设置为与要包装到的对象相同的类型?我上面有个想法,我可以通过某种方式将类型和有关此类型的其他信息(例如大小等)作为参数而不是对象本身来传递,以节省内存,但是然后如何确保将我的字段设置为与对象完全相同的类型?我无法在python中将构造函数作为参数传递,并且在python中找不到用于该任务的任何通用编程。否则我的想法完全错误。

绿色披风的家伙

您正在思考,就像使用C或Java这样的静态类型的语言一样,在这种语言中,您必须为特定类型的对象预先分配内存,然后再为其分配任何内容。这是python中的错误方法。

相反,让我们考虑一下您想要什么:一个可以表示任何单一类型,但是一旦初始化的类只能表示该特定类型的类。在Java中,您可以为此使用泛型,但是python没有这些。我们在python中可以做的是确保只能将正确类型的对象分配给它。

如果程序员不正确地使用该类,则在python中这样做的惯用方法是在运行时引发错误。静态类型检查器实际上并没有抛出Java那样好的编译时错误的好方法。我提出以下内容供您考虑:

class PrevCurr:
    @property
    def previous(self):
        return self._previous
    @previous.setter
    def previous(self, value):
        if not isinstance(value, self._type):
            raise ValueError(f"Previous value must be of type {self._type}")
        self._previous = value

    @property
    def current(self):
        return self._current
    @current.setter
    def current(self, value):
        if not isinstance(value, self._type):
            raise ValueError(f"Current value must be of type {self._type}")
        self._current = value

    def __init__(self, obj_initial):
        self._type = type(obj_initial)
        self._previous = obj_initial
        self._current = obj_initial

在这里,我们有两个面向外部的变量:previous和和current您在当前示例中一样。因为我们想要设置这些变量的特定行为,所以我们使用@property装饰器对其进行声明。它们的实际值分别保存在“专用”变量_previous和中_current

初始化后,我们检查初始对象的类型,并将该类型作为'private'变量存储到类_type

然后,每次(甚至类的实例本身)尝试设置instance.previous或时instance.current,我们都会将其重定向到适当的函数。在此函数中,我们检查要设置的对象是否与初始化类时使用的类型相同。如果没有,我们抛出一个错误。


例如,如果要存储列表或其他集合,那么我认为没有任何合理的方法可以确保整个列表保持相同的类型(或者实际上对列表内容进行任何假设),因为python本身不是。它们都是<type 'list'>)。

一种可能的解决方法是使用元类并重写__instancecheck__()metaclass方法,以创建dict仅包含特定类型对象的子类,然后PrevCurr使用其中之一来初始化您的实例。

我从类的名称假定您有一些方法.update()可以将该current复制previous,并分配一个current必须是相同类型的新值。在这种情况下,您可能需要使用getter和setter来直接进行分配previous


用法示例:

>>> a = PrevCurr(3)
>>> a.previous = 2
>>> a.previous = 4.5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in previous
ValueError: Previous value must be of type <class 'int'>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

类构造函数如何具有相同类的参数?

如何限制案例类在Scala中具有特定的参数类型构造函数?

与参数具有相同原始类型的构造函数

注入具有多个相同类型参数的构造函数

我如何创建具有与类相同的泛型作为参数的构造函数

Scala中具有协变类型参数和私有构造函数的类

如何扩展其构造函数具有类型为“Title”的参数的类-@angular/platform-browser 类型参数

在基类构造函数中使用抽象类作为参数,以在派生类中具有更多特定类型

如何在具有相同名称成员的对象的构造函数中限定类型名称?

在继承的类中具有参数的最佳实践构造函数

在具有类型参数的函数中调用的类型类方法

在C ++中,如何使构造函数具有不同类型的参数?

如何使用Mock.Of <>语法模拟在构造函数中具有参数的类?

如何在mockito中模拟具有许多构造函数参数的类?

当类构造函数具有参数时,如何在Java中初始化数组?

如何在工厂方法中初始化具有多个参数构造函数的类

如何在PHP中实例化具有参数化构造函数的.NET类?

具有类型参数的派生构造函数

具有相同类型的可变参数模板参数的构造函数无法编译

构造函数与参数具有相同类型的用途是什么?爪哇

为什么方法参数F与类型构造函数F具有相同的名称?

如何使用 kotlinpoet 生成具有单个类型参数的 Kotlin“Unit”类型的构造函数参数?

如果子类与父类具有相同的参数,则子类应该重写构造函数吗?

直接或通过构造函数初始化具有相同类型的类

在类声明中,为什么构造函数中的参数不能与私有部分中定义的变量具有相同的名称?

如何表达具有返回相同类型类值的函数的类型类

当其超类具有较少参数时,如何为子类构造函数添加更多参数?

具有与参数相同的对象的对象构造函数

具有多个相同类型实例的构造函数