Type safety in Python

I defined a Vector class that has three properties: x , y and z . Coordinates must be real numbers, but nothing prevents you from doing the following:

 >>> v = Vector(8, 7.3, -1) >>> vx = "foo" >>> vx "foo" 

I could implement "type safety" as follows:

 import numbers class Vector: def __init__(self, x, y, z): self.setposition(x, y, z) def setposition(self, x, y, z): for i in (x, y, z): if not isinstance(i, numbers.Real): raise TypeError("Real coordinates only") self.__x = x self.__y = y self.__z = z @property def x(self): return self.__x @property def y(self): return self.__y @property def z(self): return self.__z 

... but it seems non-python.

Suggestions?

+22
python type-safety
Sep 20 '10 at 8:36
source share
5 answers

You should ask yourself why you want to check the type when setting these values. Just raise a TypeError in any calculation that happens to stumble upon the wrong type . Bonus: standard operations already do this.

 >>> 3.0 / 'abc' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unsupported operand type(s) for /: 'float' and 'str' 
+17
Sep 20 '10 at 8:41
source share

Duck Typing is the usual way in Python. It should work with everything that behaves like a number, but not necessarily real number.

In most cases, Python does not need to explicitly check types. You gain flexibility because your code can be used with custom data types if they behave correctly.

+12
Sep 20 '10 at 8:44
source share

But there is nothing to do to do the following:

I believe that trying to stop someone from doing something like this is non-Python. If you need to, you should check type safety during any operations you can do using Vector , in my opinion.

To specify a GVR:

We are all adults.

eventually. See this question and its answers for more information.

I'm sure more experienced Pythonistas can give you better answers.

+4
Sep 20 '10 at 8:41
source share

Other answers already indicate that there is no point in checking type. In addition, your class will not be very fast if it is written in pure Python.

If you want more pythonic solutions, you can use property setting tools, for example:

 @x.setter def x(self, value): assert isinstance(value, numbers.Real) self.__x = value 

The assert statement will be deleted when debugging is disabled or optimization mode is activated.

Alternatively, you can force the value to be a floating point in the installer. This will throw an exception if the type / value is not convertible:

 @x.setter def x(self, value): self.__x = float(value) 
+4
Sep 20 2018-10-10T00:
source share

You should not provide type security in this way. Yes, someone can intentionally break your code by providing values โ€‹โ€‹for which your container will not work, but this is the same with other languages. And even if someone put the correct value for the parameter in a method or member function, it does not necessarily mean that it is not broken: if the program expects an IP address, but you pass the host name, it still will not work, although both can be strings.

I say: Python mentality is fundamentally different. The duck picks up basically: โ€œHey, I'm not limited to certain types, but the interface or behavior of the objects. If the object really acts like the object that I expect, I don't care - just go for it.

If you try to introduce type checking, you basically limit one of the most useful features of the language.

Speaking of which, you really need to pass testing based on testing, or at least single testing. In fact, there is no excuse not to do this with dynamic languages โ€‹โ€‹- it simply moves errors (of the type) that are detected at another stage of the build process, away from compilation time to running the test suite several times a day. Although this seems like an added effort, it will actually reduce the time spent debugging and fixing the code, since it is inherently a more powerful way to detect errors in your code.

But thatโ€™s enough, Iโ€™m already incoherent.

+2
Sep 20 '10 at 8:50
source share



All Articles