Вопрос

Я определил А. Vector Класс, который имеет три переменных свойств: x, y а также z. Отказ Координаты должны быть реальными номерами, но нечего остановить один из следующих:

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

Я мог бы реализовать «безопасность типа»:

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

... но это кажется не-питонским.

Предложения?

Это было полезно?

Решение

Вы должны спросить себя, почему вы хотите проверить тип на настройке этих значений. Просто поднять А. TypeError в любом расчете, который происходит, чтобы наткнуться на неправильное стоимость тип. Бонус: Стандартные операции уже делают это.

>>> 3.0 / 'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for /: 'float' and 'str'

Другие советы

Утка печатает обычный путь в Python. Это должно работать со всем, что ведет себя как номер, но не обязательно является реальное число.

В большинстве случаев в Python не следует явно проверять типы. Вы получаете гибкость, потому что ваш код может использоваться с пользовательскими типами данных, если они ведут себя правильно.

Другие ответы уже отметили, что он не имеет большого смысла проверять здесь тип. Кроме того, ваш класс не будет очень быстро, если он написан в чистом Python.

Если вы хотите больше Pythonic Solution - вы можете использовать сопутствующие свойства, такие как:

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

Заявление ASSERT будет удалено при отключении отладки или включенного режима оптимизации.

В качестве альтернативы, вы могли заставить value к плавающей точке в установке. Это поднимет исключение, если тип / значение не является конвертируемым:

@x.setter
def x(self, value):
    self.__x = float(value)

Но нечего остановить один из следующих:

Я верю, что пытается остановить кого-то сделать что-то подобное, это не-питон. Если вы должны, то вы должны проверить наличие безопасности в течение любые операции, которые вы можете сделать, используя Vector, я считаю.

Цитировать GVR:

Мы все взрослые.

после всего. Видеть это вопрос и его ответы для получения дополнительной информации.

Я уверен, что более опытные Pythonistas здесь могут дать вам лучшие ответы.

Вы не должны обеспечивать безопасность типа таким способом. Да, кто-то может сознательно сломать свой код, поставляя значения, для которых ваш контейнер не будет работать - но это то же самое с другими языками. И даже если кто-то поставил правильное значение для параметра в метод или функцию элементов, не обязательно означает, что он не нарушен: если программа ожидает IP-адрес, но вы передаете имя хоста, он все еще не будет работать, хотя оба могут быть строки.

То, что я говорю: мышление Python по своей природе отличается. Утка, набрав в основном, говорит: Эй, я не ограничиваясь определенными типами, а к интерфейсу или поведению объектов. Если объект делает работу, как будто это тот вид объекта, которого я ожидаю, мне все равно - просто пойти на это.

Если вы попытаетесь ввести проверку типа, вы в основном ограничиваете одну из самых полезных функций языка.

Это, как говорится, вам действительно нужно войти в тестовое развитие, или по меньшей мере, тестирование единицы. На самом деле нет оправдания, чтобы не делать это с динамическими языками - это просто перемещение ошибок (тип), которые обнаруживаются на другой шаг в процессе сборки, вдали от времени компиляции для проведения тестового набора несколько раз в день. Хотя это кажется дополнительным усилием, он фактически сократит время, потраченную на отладку и крепежный код, поскольку он является более мощным способом обнаружения ошибок в вашем коде.

Но достаточно этого, я уже бессвязанный.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top