提高pythonic异常

时间:2016-05-05 12:12:06

标签: python python-3.x exception python-3.5

Python 3.5.1 .. 我有一些代码需要用来引发异常。我想知道这是否是“pythonic”的做法。我在其他地方被告知我应该使用try / except,但是,在这种情况下,我已被特别指示使用:

  • if:raise / else
  • LocationError必须接受一个输入,位置
  • LocationError必须从Exception类继承

鉴于这些限制,有没有“更好”的方法呢?

location = [1, 2]

def update_loc(oldloc, newloc):
    if oldloc == newloc:
        raise LocationError('Location match, old location = {0}'.format(newloc))
    else:
        oldloc = newloc
    return oldloc

class LocationError(Exception):
    def __init__(self, location):
        self._location = location #initial code
        super().__init__(location) #fixed code

location = update_loc(location, [1, 2])

因此,我被告知,问题在于我不是从Parent类继承的,(例外)。我想为异常创建一个子类就是这样,仅此而已。

2 个答案:

答案 0 :(得分:1)

从您的描述中

  1. 定义LocationError异常类
  2. 如果位置匹配,则在update_loc函数中提出该异常,并
  3. update_loc块内调用try..except以捕获异常。
  4. 这里有一些代码可以做到这一点。

    class LocationError(Exception):
        def __init__(self, location):
            self.location = location
    
    def update_loc(oldloc, newloc):
        if oldloc == newloc:
            raise LocationError(newloc)
        return newloc
    
    location = [1, 2]
    
    for data in ([1, 2], [3, 4], [3, 4], [1, 2]):
        try:
            location = update_loc(location, data)
            print('New location = {0}'.format(location))
        except LocationError as e:
            print('LocationError: new location matches old location = {0}'.format(e.location))
    

    <强>输出

    LocationError: new location matches old location = [1, 2]
    New location = [3, 4]
    LocationError: new location matches old location = [3, 4]
    New location = [1, 2]
    

    请注意,分配给oldloc中的update_loc没有意义:只创建一个update_loc本地的新列表。但是,因为这些位置是列表,所以 可以在函数内改变它们。

    例如,你可以做到

    def update_loc(oldloc, newloc):
        if oldloc == newloc:
            raise LocationError(newloc)
        oldloc[:] = newloc
    
    location = [1, 2]
    
    for data in ([1, 2], [3, 4], [3, 4], [1, 2]):
        try:
            update_loc(location, data)
            print('New location = {0}'.format(location))
        except LocationError as e:
            print('LocationError: new location matches old location = {0}'.format(e.location))
    

    将产生与早期代码相同的输出。

答案 1 :(得分:0)

似乎你在混淆一些概念。通常,异常处理定义了如何处理尝试执行不可能的操作的情况。在python中你引发了一个异常,你可以除外并处理它。

i = input("Give me a number")
try:
    # the following line will raise an ZeroDivisionError
    print(5/i)
except ZeroDivisonError:
    print("You can't insert 0")

如果检测到错误状态,也可以手动引发异常/错误:

class Person

    def __init__(self, age):
        if age < 0:
            raise ValueError("Age can't be below zero")

提出异常并不是另一种方法。

但是有多种方法可以处理异常。第一个是尽可能地防止它们(在你跳跃之前看,称为LBYL)。

age = input("What is your age?")
if age < 0:
    print("You can't be of a negative age.")
    exit(1)
person = Person(age)

或者你可以简单地尝试做你想做的事情并在以后捕捉任何例外:

age = input("What is your age?")
try:
    person = Person(age)
except ValueError:
    print("You can't be of a negative age.")

这通常被称为“#34;更容易请求宽恕而非许可&#34; (称为EAFP)。

在python中,通常首选EAFP。