how to make a field of the class to be of the same type as parameter in constructor

gehirndienst

I'm a fully "static typed" man and a beginner in python and I want to make a datatype in python, which saves prev-next states of some objects. The structure is like this:

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

No problem if my obj_initial is something like [None, None] or so. But imagine I need to wrap this class onto the different big types, like dictionaries/lists/sets of 1000+ elements or/and user-defined classes. Then I would like to have something like this:

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 = ...

My question is: how to be sure, that fields (or is there another name in python for them?) are set to be of the same type as the object, onto which I want to wrap? I have the idea presented above, that I may somehow to pass the type and additional info about that, like size and etc. as parameters instead of object itself to save the memory, but how then to ensure, that my fields are set to be exactly the same type as the object? afaik I cannot pass constructors as parameters in python and I couldn't find any sort of generic programming in python for that task. Or I got the idea fully wrong.

Green Cloak Guy

You're thinking as you would in a static-typed language like C or Java, where you have to pre-allocate memory for objects of a specific type before assigning anything to them. This is the wrong approach in python.

Instead, let's consider what you want: a class that can represent any single type, but which, once initialized, can only represent that particular type. In Java, you would use a generic for this, but python doesn't have those. What we can do in python is to make sure that only objects of the correct type can be assigned to it.

The idiomatic way of doing something like this in python is throwing an error at runtime if the programmer uses the class incorrectly; there's not really a good way for a static typechecker to throw a compile-time error, like it might in Java. I present the following for your consideration:

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

Here, we have two external-facing variables: previous and current, as you have in your current example. Because we want specific behaviors on setting these variables, we use the @property decorator to declare them. Their actual values are held in the 'private' variables _previous and _current, respectively.

Upon initialization, we check the type of the initial object, and store that type to the class as the 'private' variable _type.

Then, each time something (even the class's instance itself) tries to set instance.previous or instance.current, we redirect it to the appropriate function. In this function, we check whether the object to be set is the same type as what we initialized the class with. If not, we throw an error.


If you're storing, for example, a list or other collection, then I don't think there's any reasonable way to ensure that the entire list remains the same type (or, indeed, to make any assumption about the contents of the list, since python itself doesn't. They're all <type 'list'>).

One possible workaround would be to use metaclasses and overriding the __instancecheck__() metaclass method, to create a subclass of dict that only holds a specific type of object, and then initialize your PrevCurr instance with one of those.

I presume from the name of the class that you have some method .update() that copies over the current value to previous, and assigns a new current value that must be the same type. In that case you might want to play around with the getters and setters to make assigning directly to previous harder.


Example of usage:

>>> 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'>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to create a Scala class with private field with public getter, and primary constructor taking a parameter of the same name

From Dev

How to make sure an iterator template parameter has the same data type as the template parameter of a template class

From Dev

How to pass a type parameter to a generic class constructor reference?

From Dev

How to pass a type parameter to a generic class constructor reference?

From Dev

How to make a method a parameter for a constructor

From Dev

How to extend a class whose constructor has a parameter with type "Title" - @ angular / platform-browser type parameter

From Dev

How to use a constructor parameter within the same constructor?

From Dev

Constructor result type is not <:< class type on class with type parameter

From Dev

Constructor result type is not <:< class type on class with type parameter

From Dev

How do I use the same variable name of a local variable and a constructor parameter in the same class?

From Dev

How to create a Class with multiple constructors that use the same parameter type

From Dev

Class with covariant type parameter and private constructor in Scala

From Dev

Passing parameter to the constructor of a generic Class type

From Dev

Detect the type of parameter passed in class constructor

From Dev

Class with covariant type parameter and private constructor in Scala

From Dev

How to make a constructor of a generic type

From Dev

How to make multiple template class to have the same type

From Dev

How to pass a field constructor parameter to a function?

From Dev

How to pass a field constructor parameter to a function?

From Dev

how to make a class that can be initialized using object or regular parameter constructor in Typescript?

From Dev

how to type in input field that have the same class name with another input field in Laravel Dusk

From Dev

How to Select Choices input field having same class, type, Xpath everything is same

From Dev

How to initialize a new field of an inner class with constructor?

From Dev

How to initialize a new field of an inner class with constructor?

From Dev

How does the EnumConverter Constructor get the Type Parameter

From Dev

How to pass parameter to static class constructor?

From Dev

How to use IEnumerable<T> in a class constructor parameter

From Dev

How to pass template parameter from class constructor

From Dev

What is the use for a constructor take the same type as a parameter? Java

Related Related

  1. 1

    How to create a Scala class with private field with public getter, and primary constructor taking a parameter of the same name

  2. 2

    How to make sure an iterator template parameter has the same data type as the template parameter of a template class

  3. 3

    How to pass a type parameter to a generic class constructor reference?

  4. 4

    How to pass a type parameter to a generic class constructor reference?

  5. 5

    How to make a method a parameter for a constructor

  6. 6

    How to extend a class whose constructor has a parameter with type "Title" - @ angular / platform-browser type parameter

  7. 7

    How to use a constructor parameter within the same constructor?

  8. 8

    Constructor result type is not <:< class type on class with type parameter

  9. 9

    Constructor result type is not <:< class type on class with type parameter

  10. 10

    How do I use the same variable name of a local variable and a constructor parameter in the same class?

  11. 11

    How to create a Class with multiple constructors that use the same parameter type

  12. 12

    Class with covariant type parameter and private constructor in Scala

  13. 13

    Passing parameter to the constructor of a generic Class type

  14. 14

    Detect the type of parameter passed in class constructor

  15. 15

    Class with covariant type parameter and private constructor in Scala

  16. 16

    How to make a constructor of a generic type

  17. 17

    How to make multiple template class to have the same type

  18. 18

    How to pass a field constructor parameter to a function?

  19. 19

    How to pass a field constructor parameter to a function?

  20. 20

    how to make a class that can be initialized using object or regular parameter constructor in Typescript?

  21. 21

    how to type in input field that have the same class name with another input field in Laravel Dusk

  22. 22

    How to Select Choices input field having same class, type, Xpath everything is same

  23. 23

    How to initialize a new field of an inner class with constructor?

  24. 24

    How to initialize a new field of an inner class with constructor?

  25. 25

    How does the EnumConverter Constructor get the Type Parameter

  26. 26

    How to pass parameter to static class constructor?

  27. 27

    How to use IEnumerable<T> in a class constructor parameter

  28. 28

    How to pass template parameter from class constructor

  29. 29

    What is the use for a constructor take the same type as a parameter? Java

HotTag

Archive