Lors de l'implémentation d'une exception personnalisée pour mon module, je me suis intéressé à la façon dont l'arborescence des exceptions intégrées diffère entre Python 2 et 3. J'ai donc décidé d'étudier la différence dans l'arborescence de chaque version.
En conclusion, il a été constaté que "la structure arborescente des exceptions diffère considérablement selon la version même dans le 3ème système, et non en premier lieu la distinction entre le 2ème système et le 3ème système". Veuillez noter que si vous pensez que l'arborescence des exceptions est la même en 3 séries, vous pouvez avoir des problèmes inattendus.
print_exc_tree.py
#!/usr/bin/env python
from __future__ import print_function
import platform
def classtree(cls, depth=0):
if depth == 0:
prefix = ''
else:
prefix = '.' * (depth * 3) + ' '
if cls.__name__.lower() == 'error':
print('{0}{1} ({2})'.format(prefix, cls.__name__, cls))
else:
print('{0}{1}'.format(prefix, cls.__name__))
for subcls in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
classtree(subcls, depth+1)
if __name__ == '__main__':
print('Python Version: {0}'.format(platform.python_version()))
print()
classtree(BaseException)
2.7.12 V.S. 3.5.2
Comparez les deux derniers au moment de la rédaction. Fondamentalement, cela devrait être OK si vous êtes conscient de cette différence dans la structure arborescente.
$ pyenv shell 2.7.12
$ python print_exc_tree.py
Python Version: 2.7.12
BaseException
... Exception
...... Error (<class 'locale.Error'>)
...... StandardError
......... ArithmeticError
............ FloatingPointError
............ OverflowError
............ ZeroDivisionError
......... AssertionError
......... AttributeError
......... BufferError
......... EOFError
......... EnvironmentError
............ IOError
............... ItimerError
............ OSError
......... ImportError
............ ZipImportError
......... LookupError
............ CodecRegistryError
............ IndexError
............ KeyError
......... MemoryError
......... NameError
............ UnboundLocalError
......... ReferenceError
......... RuntimeError
............ NotImplementedError
......... SyntaxError
............ IndentationError
............... TabError
......... SystemError
............ CodecRegistryError
......... TypeError
......... ValueError
............ UnicodeError
............... UnicodeDecodeError
............... UnicodeEncodeError
............... UnicodeTranslateError
...... StopIteration
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ pyenv shell 3.5.2
$ python print_exc_tree.py
Python Version: 3.5.2
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... OSError
......... BlockingIOError
......... ChildProcessError
......... ConnectionError
............ BrokenPipeError
............ ConnectionAbortedError
............ ConnectionRefusedError
............ ConnectionResetError
......... FileExistsError
......... FileNotFoundError
......... InterruptedError
......... IsADirectoryError
......... ItimerError
......... NotADirectoryError
......... PermissionError
......... ProcessLookupError
......... TimeoutError
......... UnsupportedOperation
...... ReferenceError
...... RuntimeError
......... BrokenBarrierError
......... NotImplementedError
......... RecursionError
......... _DeadlockError
...... StopAsyncIteration
...... StopIteration
...... StopTokenizing
...... SubprocessError
......... CalledProcessError
......... TimeoutExpired
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
Je suis un peu inquiet pour sre_constants.error
, mais cela semble être utilisé lorsque l'expression régulière est ambiguë (Reference)
Python 3.5.2 (default, Jul 29 2016, 11:13:25)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.compile("*kittens*")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/re.py", line 224, in compile
return _compile(pattern, flags)
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/re.py", line 293, in _compile
p = sre_compile.compile(pattern, flags)
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/sre_compile.py", line 536, in compile
p = sre_parse.parse(p, flags)
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/sre_parse.py", line 829, in parse
p = _parse_sub(source, pattern, 0)
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/sre_parse.py", line 437, in _parse_sub
itemsappend(_parse(source, state))
File "/Users/dmiyakawa/.pyenv/versions/3.5.2/lib/python3.5/sre_parse.py", line 638, in _parse
source.tell() - here + len(this))
sre_constants.error: nothing to repeat at position 0
Si vous étudiez, vous pouvez voir que cette arborescence a considérablement changé en fonction de la version, même dans le 3ème système. Cela peut sembler un peu redondant, mais regardons 3.0, 3.1, 3.2, 3.3 et 3.4 dans l'ordre.
$ pyenv shell 3.0.1
$ python print_exc_tree.py
Python Version: 3.0.1
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... EnvironmentError
......... IOError
............ BlockingIOError
............ ItimerError
............ UnsupportedOperation
......... OSError
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... ReferenceError
...... RuntimeError
......... NotImplementedError
...... StopIteration
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... error (<class '_thread.error'>)
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ pyenv shell 3.1.5
$ python print_exc_tree.py
Python Version: 3.1.5
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... EnvironmentError
......... IOError
............ BlockingIOError
............ ItimerError
............ UnsupportedOperation
......... OSError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... ReferenceError
...... RuntimeError
......... NotImplementedError
...... StopIteration
...... StopTokenizing
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ pyenv shell 3.2.6
$ python print_exc_tree.py
Python Version: 3.2.6
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... CalledProcessError
...... EOFError
...... EnvironmentError
......... IOError
............ BlockingIOError
............ ItimerError
............ UnsupportedOperation
......... OSError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... PickleError
......... PicklingError
......... UnpicklingError
...... PickleError
......... PicklingError
......... UnpicklingError
...... ReferenceError
...... RuntimeError
......... NotImplementedError
...... StopIteration
...... StopTokenizing
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... _Stop
...... error (<class 'sre_constants.error'>)
...... error (<class '_thread.error'>)
...... error (<class 'select.error'>)
...... error (<class 'struct.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ pyenv shell 3.3.6
$ python print_exc_tree.py
Python Version: 3.3.6
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... OSError
......... BlockingIOError
......... ChildProcessError
......... ConnectionError
............ BrokenPipeError
............ ConnectionAbortedError
............ ConnectionRefusedError
............ ConnectionResetError
......... FileExistsError
......... FileNotFoundError
......... InterruptedError
......... IsADirectoryError
......... ItimerError
......... NotADirectoryError
......... PermissionError
......... ProcessLookupError
......... TimeoutError
......... UnsupportedOperation
...... ReferenceError
...... RuntimeError
......... NotImplementedError
......... _DeadlockError
...... StopIteration
...... StopTokenizing
...... SubprocessError
......... CalledProcessError
......... TimeoutExpired
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ pyenv shell 3.4.3
$ python print_exc_tree.py
Python Version: 3.4.3
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... OSError
......... BlockingIOError
......... ChildProcessError
......... ConnectionError
............ BrokenPipeError
............ ConnectionAbortedError
............ ConnectionRefusedError
............ ConnectionResetError
......... FileExistsError
......... FileNotFoundError
......... InterruptedError
......... IsADirectoryError
......... ItimerError
......... NotADirectoryError
......... PermissionError
......... ProcessLookupError
......... TimeoutError
......... UnsupportedOperation
...... ReferenceError
...... RuntimeError
......... BrokenBarrierError
......... NotImplementedError
......... _DeadlockError
...... StopIteration
...... StopTokenizing
...... SubprocessError
......... CalledProcessError
......... TimeoutExpired
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
Je viens d'enquêter sur les détails, donc je vais le laisser ici, mais ici je porterai une attention particulière au fait que ʻIOError a disparu dans Python 3.3, et que la structure d'héritage autour de ʻOSError
a radicalement changé. C'est également l'une des différences majeures entre les systèmes 2 et 3 actuels.
Il s'agit d'un changement basé sur «PEP 3151 --Renouvellement de la hiérarchie des exceptions OS et IO». Vous pouvez voir les détails en lisant le même PEP, mais il semble qu'un facteur majeur est que l'erreur au moment de l'opération de fichier a été partagée entre ʻIOError et ʻOSError
.
>>> os.remove("fff")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: 'fff'
>>> open("fff")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'fff'
Il n'y a pas de grande différence entre 3,3, 3,4 et 3,5 à ce niveau. Au niveau de l'arborescence, il semble que de nouvelles classes d'exceptions ont été ajoutées (BrokenBarrierError
dans 3.3 → 3.4, RecursionError
et StopAsyncIteration
dans 3.4 → 3.5).
Cependant, étant donné que le changement de comportement de chaque fonction n'est pas connu dans l'arborescence, si vous êtes intéressé, veuillez lire attentivement le journal des modifications, etc., y compris la différence de la version mineure.
Supplément (05/08/2017): Dans la version précédente, c'était 3.6.0b2, mais comme la version officielle est sortie en 3.6, ce sera 3.6.2. Je ne réviserai pas toute la phrase pour le moment.
Suite au flux ci-dessus, j'ai également examiné l'arborescence 3.6.2 actuellement en cours de développement.
Python Version: 3.6.2
BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ModuleNotFoundError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... OSError
......... BlockingIOError
......... ChildProcessError
......... ConnectionError
............ BrokenPipeError
............ ConnectionAbortedError
............ ConnectionRefusedError
............ ConnectionResetError
......... FileExistsError
......... FileNotFoundError
......... InterruptedError
......... IsADirectoryError
......... ItimerError
......... NotADirectoryError
......... PermissionError
......... ProcessLookupError
......... TimeoutError
......... UnsupportedOperation
...... ReferenceError
...... RuntimeError
......... BrokenBarrierError
......... NotImplementedError
......... RecursionError
......... _DeadlockError
...... StopAsyncIteration
...... StopIteration
...... StopTokenizing
...... SubprocessError
......... CalledProcessError
......... TimeoutExpired
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Verbose
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 'sre_constants.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit
$ diff /tmp/352.txt /tmp/362.txt
1c1
< Python Version: 3.5.2
---
> Python Version: 3.6.2
14a15
> ......... ModuleNotFoundError
65a67
> ...... Verbose
Il y a deux nouvelles exceptions, mais cela ne semble pas non plus être un changement essentiel.
ModuleNotFoundError
Verbose
sre_parse.Verbose
, cela semble être une classe utilisée autour des expressions régulières. Les détails n'ont pas été étudiés.Cliquez ici pour plus d'informations sur la version 3.6: https://docs.python.org/3.6/whatsnew/3.6.html (Parce qu'il est mis à jour avec les dernières informations de 3.6, ce n'est pas nécessairement 3.6.2 ci-dessus!)
Supplément 2 (12/12/2017): La différence entre la version 3.6.2 et la dernière version 3.6.7 au moment de la mise à jour est indiquée ci-dessous.
$ diff 362.txt 367.txt
1c1
< Python Version: 3.6.2
---
> Python Version: 3.6.7
$ diff 367.txt 371.txt
1c1
< Python Version: 3.6.7
---
> Python Version: 3.7.1
80c80
< ...... error (<class 'sre_constants.error'>)
---
> ...... error (<class 're.error'>)
Il n'y a pas de grande différence.
Référence: https://docs.python.org/3.7/whatsnew/3.7.html
Si vous utilisez des exceptions d'exécution Python directement dans votre module, vous ne pourrez pas distinguer votre module des erreurs d'exécution Python (par exemple RuntimeError
ou ʻOSError`). Fondamentalement, il est courant de créer une exception de base dans votre propre module et de créer une arborescence de classes d'exceptions à partir de cela. C'est un concept que l'on retrouve souvent dans d'autres langages qui ont introduit l'idée d'exceptions.
Si vous créez votre propre système d'exceptions à structure arborescente, Python recommande d'hériter de ʻException` ou de ses sous-classes comme classe d'exception de base (http://docs.python.jp/3/library/exceptions). .html).
Vous pouvez sous-classer la classe d'exceptions intégrée pour définir de nouvelles exceptions. Nous recommandons que les nouvelles exceptions dérivent d'Exception ou de ses sous-classes au lieu de BaseException. Pour plus d'informations sur la définition des exceptions, consultez la section Exceptions définies par l'utilisateur du didacticiel Python.
Un mot sur une autre langue, Ruby.
Selon "Effective Ruby", "StandardError" est une bonne classe de base pour créer des exceptions personnalisées. Il y a une classe avec le même nom dans la 2ème série, mais il n'y a pas de classe d'exception dans la série Python 3 en premier lieu, alors considérez ʻException` et ses sous-classes.
Soyez conscient des différences subtiles dans les conventions, les règles et les conventions lorsque vous basculez entre plusieurs langages de programmation.
2016-09-14
2016-10-24
2016-10-25
Avec le recul, il aurait peut-être été plus gentil d'utiliser cls .__ module__! = 'Builtins'
que cls .__ name__. Lower () ==' error'
dans la branche de code de validation ci-dessus. ne pas. Nous prévoyons de le faire la prochaine fois que nous apporterons une solution majeure.
Le titre dit "Arborescence des exceptions intégrée", mais l'arborescence affichée est en fait une classe d'exceptions "builtins" (intégrée) qui ne nécessite aucune importation comme ʻExceptionet ʻio.UnsupportedOperation. Il existe des classes d'exception telles que
qui ne peuvent pas être lues sans importer un module. Ainsi, par exemple, lorsque vous pensez "Hmm, qu'est-ce que" Verbose "" et que vous le recherchez?
Python 3.6.0b2 (default, Oct 25 2016, 09:04:16)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> help(Verbose)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Verbose' is not defined
>>> import sre_parse
>>> help(sre_parse.Verbose)
(L'aide s'affiche)
Et semer la confusion.
2017-08-05
Nous avons adopté 3.6.2 au lieu de 3.6.0b2. Pour référence, le résultat de 3.7-dev est affiché.
2018-12-12
RuntimeError
devrait également être considéré comme un candidat pour examen", mais je l'ai supprimé. Il est difficile de séparer l'erreur et la gestion des erreurs du runtime Python, il est donc préférable de l'arrêter.StopTokenizing`` SubprocessError
" disparaître ", mais il est plus probable qu'il y ait un problème avec le script utilisé pour l'enquête. Si vous êtes intéressé, essayez-le à portée de main.2020-03-29
La suite est un article séparé.
https://qiita.com/amedama/items/e1a605c004d1e2276778
En même temps, j'ai écrit à propos de ce qui précède " StopTokenizing
SubprocessError
disparaît de la liste d'exceptions". Le fait est que "les parents n'ont aucun moyen de connaître leurs enfants car ils ne sont pas chargés au démarrage de l'exécution", mais cela ne semble pas disparaître de l'implémentation.
Recommended Posts