2015-02-06 2 views
1

Учитывая следующий код в foo.py:Импортирующие Исключения Python

class Error(Exception): 
pass 

class UnexpectedParameterType(Error): 
pass 

class Human(models.Manager): 

    def create_human(self, name): 

     if not isinstance(name, str): 
      raise UnexpectedParameterType 

     human = Human(name = name) 
     return human 

ли я абсолютно необходимо явно импортировать свой класс исключений в bar.py, так что я могу поймать исключение броска? Как это:

from foo import UnexpectedParameterType, Human 

human = Human() 
try: 
    human.create_human(123) 
except UnexpectedParameterType: 
    return "Cannot create human." 

Что я намекаю на здесь быть в состоянии сделать что-то вроде этого:

from foo import Human 

[...] 

except Human.UnexpectedParameterType: 
    return "Cannot create human." 

Все ответы очень высокую оценку, спасибо! Не стесняйтесь делиться своими личными рекомендациями по устранению исключений в Python.

ответ

2

Вы не можете сделать Human.UnexpectedParameterType, так как Human не имеет атрибута UnexpectedParameterType.

Вот почему вы обычно хотите сделать import foo не from foo import .... Легче проследить, что происходит, если вы это сделаете.

Что вы МОЖЕТЕ сделать, это создать базовый класс, который имеет свои собственные исключения, прикрепленные к нему. Это может быть что-то вроде

# foo.py 

class Human(object): 
    class Error(Exception): 
     pass 

    class UnexpectedParameterType(Error): 
     pass 

    def throw_bad_parm(self): 
     raise self.UnexpectedParameterType 

    # the rest of your function in Human 

DEMO:

import foo 

a = foo.Human() 
try: 
    a.throw_bad_parm() 
except foo.Human.UnexpectedParameterType as e: 
    print("You can't do that because of {!r}".format(e)) 

# You can't do that because of UnexpectedParameterType() 

Это работает во многом так же, как @staticmethod делает - вы пакетирование вещи, которые логически часть вашего кода в других классах, даже хотя они не полагаются на эти классы для работы. Таким образом, вы могли бы сделать что-то вроде:

class HTTPHandler(object): 
    class Exception404(Exception): pass 
    class Exception403(Exception): pass 
    ... 
+0

Вот что я подумал, но если вы вспомните в Django, вы можете сделать что-то вроде MyModel.DoesNotExist, где MyModel - это класс, а не файл. Это в основном то, что я пытаюсь сделать и в моем коде. – heapoverflow

+0

@heapoverflow вы не можете помещать блоки текста в комментарии. [gisthub] (https://gist.github.com/) подходит для этого –

+0

Кроме того, я вижу, что вы кладете класс внутри другого класса. Является ли это законным в Python? – heapoverflow

2

Вы не можете сделать Human.UnexpectedParameterType, потому что UnexpectedParameterType не является атрибутом на Human класса; он является частью модуля foo. Вы могли бы сделать что-то вроде этого

import foo 

human = foo.Human() 
try: 
    human.create_human(123) 
except foo.UnexpectedParameterType: 
    return "Cannot create human." 

В противном случае вам необходимо явно импортировать его.


В данном конкретном случае, однако, Python уже есть исключение для представления плохих типов: TypeError. Итак, вместо этого вы можете поднять TypeError, а затем поймать TypeError. (TypeError - это встроенный тип, поэтому вы явно не импортируете его.)

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