2012-06-25 2 views
0

Я получаю основную философию, не прошу разрешения, просто сделайте это и попросите прощения. Например, не нужно, чтобы файл имел метод .read(), вы позже поблагодарите себя, когда найдете что-то «просто работаете», когда хотите прочитать файл-подобный объект. Тем не менее, это почти проще, когда я обхожусь вокруг сложных объектов, таких как файлы, чем простые объекты, такие как числа.Pythonic способ сравнить ненадежные простые аргументы

Итак, я пытаюсь написать очень простой класс. Детали не имеют значения, но он имеет внутренний счетчик и должен что-то делать, когда счетчик превышает лимит. Предел предоставляется в качестве аргумента при создании объекта.

Теперь я думаю о защитном программировании. Очевидно, я бы хотел, чтобы мой предел был целым числом или, по крайней мере, чем-то, что сравнивается как целое число. Он может быть слабее, потому что тест> = test все равно будет обеспечивать правильное поведение, если это float.

Хотя пользователь класса будет знать, что этот аргумент должен быть целым числом, я хотел бы, чтобы объект делал что-то неудивительное, если это не так. Моя первая мысль была, чтобы проверить, что я на самом деле имел ряд по

if isinstance(limit,(int,long,float)): 

но есть любое количество «не испытывает, попробуйте кроме» ответов на здесь, так что я знаю, что это unpythonic. Лучше использовать предел и ждать, пока не будет выбрано исключение. Так что я попытался это внутри попробовать: для различных типов предела

if counter >= limit: 

Это прекрасно работает, как ожидалось, если предел является INT или поплавок, за исключением. Затем я сделал ограничение строкой или кортежем, объекты, для которых сравнение с числом не имеет никакого очевидного или разумного определения, и ждали, чтобы поймать исключение. Но он выполняет, возвращает логическое значение и остается безмолвным.

Итак, я RTFM, и получается, что сравнение не вызывает исключения для смешанных типов, что-то связанное с операцией «x в контейнере», для которой равенство проверяется на произвольных типах. Он всегда возвращает not_equal для разных типов, но сравнение величин, в то время как последовательное, произвольно. Я мог бы, возможно, использовать его, если смешанный тип сравнения величин всегда возвращался False, но он с радостью вернет Истину.

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

limit+0 

Так что я мог бы сказать

if counter >= (limit+0) 

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

Четкая возможность является

if counter >= int(limit) 

, который по крайней мере, есть некоторые объяснения построено. Это не делает именно то, что я хотел бы случиться при любых обстоятельствах, но это не достаточно на данный момент , и это никого не удивит.

Итак, WWGD? Какой питонский способ безопасно использовать ненадежный аргумент, когда все, что вы хотите сделать, это сравнить его по величине?

+0

Поздравляем, теперь вы готовы к поиску «Ягни» и понимаете его. – Kos

+0

Спасибо, у меня есть, там много читается на c2.com. К сожалению, тупой пользователь, который передал строку тому, что нужно было сравнить, как int, был мной, поэтому я чувствую, что мне это понадобится. Но часть того, что я делаю, изучает Python, а также записывает нужные мне вещи, и я как бы играю с такими способами. Но я все равно хотел бы знать, что такое Путинский путь. –

+0

Что вам не нужно здесь, это слишком большая родословность, а не защитное программирование. Будет ли вам _ever_ нужен ли счетчик, который является чем-то другим, чем int? Считаете ли вы, что это важная концепция, которая требует слоя абстракции? – Kos

ответ

0

Если вы действительно хотите, чтобы убедиться, что аргумент подходящего числового типа, затем проверить, является ли экземпляр соответствующего numeric abstract base class, возможно:

import numbers 
    ... 
    if not isinstance(limit, numbers.Real): 
     ... # react to the bad argument type 

Предположительно в этом случае вы будете бросать исключение TypeError.

Сделайте это в своем классе __init__, чтобы проблема была обнаружена и сообщалась как можно ближе к исходной ошибке вызывающего абонента. Это намного добрее, чем ждать некоторого неопределенного количества времени и, в конце концов, взорваться, когда программа приближается к игре со счетчиком, и в этом случае трассировка исключения будет гораздо менее полезна для определения генезиса проблемы.

Если вы чувствуете себя параноиком, вы также можете проверить конструктор, что значение этого аргумента больше нуля, и выбросить исключение ValueError, если это не так.

 Смежные вопросы

  • Нет связанных вопросов^_^