[Tutor PyCZ] Kde najdu Exception arguments

Petr Prikryl PrikrylP na skil.cz
Pondělí Srpen 15 09:17:37 CEST 2005


geon napsal...
> Oktavian Glider napsal
> 
> > Potřebuji vědět jaký počet argumentů mají 
> > jednotlivé exceptions. [...] Kde najdu nějaký
> > seznam argumentů k jednotlivým exeptions? 
> [...]
> myslím, že se to vždy předává jako tuple, 
> jen někdy, často má tuple jen jeden prvek, 
> takže se automaticky přiřazuje do proměnné
> jako řetězec. [...]

Standardní třída Exceptions() může mít libovolný
počet argumentů. Záleží na uživateli, kolik jich
použije. 

Vnitřně se uchovávají v podobě n-tice (tuple, 
tedy později neměnitelné struktury). Je přístupná 
prostřednictvím atributu args. Příklad:

  >>> e = Exception(1, 'ahoj', 3)
  >>> e
  <exceptions.Exception instance at 0x00925F80>  
  >>> e.args
  (1, 'ahoj', 3)
  >>> type(e.args)
  <type 'tuple'>

Jejich konkrétní počet můžu zjistit stejně, 
jako zjišťuji počet prvků n-tice:

  >>> len(e.args)
  3

Indexováním můžeme zpřístupňovat jednotlivé
argumenty z args (jako u každé běžné n-tice).
  
  >>> e.args[0]
  1
  >>> e.args[1]
  'ahoj'
  >>> e.args[2]
  3
  >>> e.args[3]
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  IndexError: tuple index out of range

Protože je definována metoda __getitem__(), 
můžeme argumenty zpřístupňovat i indexováním
samotného objektu:

  >>> e[0]
  1
  >>> e[1]
  'ahoj'
  >>> e[2]
  3
  >>> e[3]
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  IndexError: tuple index out of range

Metoda __str__() je definována tak, aby se 
zobrazila řetězcová reprezentace argumentů.
Její výsledek typicky získáváme prostřednictvím
zabudované funkce str() nebo dosazením do příkazu
print:

  >>> print e
  (1, 'ahoj', 3)
  >>> str(e)
  "(1, 'ahoj', 3)"

S výše uvedenými znalostmi bych mohl definovat
svou vlastní bázovou třídu pro výjimky s podobnými
vlastnostmi takto:

  class MyException:
      """Common base class for all MY exceptions."""

      def __init__(self, *args):
          self.args = tuple(args)

      def __getitem__(self, i):
          return self.args[i]

      def __str__(self):
          return 'My exception: ' + str(self.args)

Standardní třída Exceptions nemá pythonovský
zdrojový text, protože je implementována přímo
v jádře jazyka, ale její definice by mohla 
vypadat téměř stejně -- takto:

  class Exception:
      """Common base class for all exceptions."""

      def __init__(self, *args):
          self.args = tuple(args)

      def __getitem__(self, i):
          return self.args[i]

      def __str__(self):
          return str(self.args)

Vyvolání výjimky a její odchycení může v dokumentaci
vypadat trochu zmateně, protože se dříve výjimky 
realizovaly v podobě řetězcových objektů. V současnosti
se mají vždy používat výjimky odvozené od Exception.
Při vyvolávání výjimky si typicky objekt reprezentující
výjimku vytvářím -- doporučuje se zápis vyjadřující
konstrukci nového objektu:


  try:
      ...
      raise Exception(1, 'ahoj', 3)
      ...

Při odchytávání výjimky se definuje především
typ odchytávané výjimky (tj. typ objektu výjimky:

  except Exception:
      print 'Nastala vyjimka.'

Volitelně můžeme uvést jméno, které bude spojeno 
s konkrétní instancí výjimky (s konkrétním objektem).
Jeho prostřednictvím si můžeme zpřístupnit argumenty
výjimky:

  except Exception, e:
      # e zpřístupňuje objekt výjimky.
      print e.args
      print e
      print len(e.args)
      for arg in e.args:
          print arg

... případně po zpracování argumentů můžeme 
výjimku znovu zápisem raise bez argumentů 
nebo, v našem případě, zápisem "raise e".
V druhém případě můžu před opakovaným vyvoláním
výjimky přiřadit do e.args novou n-tici, takže
vlastně můžu upřesnit nebo zcela změnit argumenty
výjimky. Systému je to jedno, ten se o argumenty
výjimky nestará. Je to čistě uživatelská záležitost.

Všechny ostatní formy zápisu (pokud se nepletu) jsou
dědictvím minulosti a nedoporučuje se je používat.




pepr   


Další informace o konferenci Tutor