2016-03-31 3 views
4

Je viens de découvrir des annotations de fonctions pour python 3 (https://www.python.org/dev/peps/pep-3107/) qui semble parfait pour documenter les paramètres ou les types de retour. Il rend également mieux intellisense disponible dans mon IDE pycharm.annotations de fonction en python

J'ai une question concernant les paramètres où le type d'entrée est flou. Par exemple, il peut s'agir d'une liste ou d'un tableau numpy ou d'une quantité de type "tableau". Quel est le meilleur moyen d'annoter un tel paramètre d'entrée dans la fonction? Exemple:

import numpy as np 

def fun(data: np.ndarray) # can also be a list 
    pass 

J'ai un autre cas où l'entrée peut être l'un des deux types. Exemple:

def fun(header: Nifti1Header) # can also be Nifti2Header 
    pass 

Quelle est la meilleure façon de documenter ces types d'entrées de paramètres?

Répondre

5

Si vous utilisez python3.5, la meilleure façon est d'utiliser typing.Union

>>> from typing import Union 
>>> import numpy as np 
>>> def fun(data: Union[np.ndarray, list]): 
     pass 

Vous pouvez également utiliser typing.TypeVar si vous utilisez toujours Union [t1, t2, ...] . (De plus, vous pouvez ajouter et supprimer des types de la TypeVar plus facilement que de nombreux syndicats dans votre code)

>>> from typing import TypeVar 
>>> import numpy as np 
>>> import array 
>>> Ar = TypeVar('Ar', np.ndarray, list, array.array) 

Ce code serait alors associer Ar avec des listes, array.arrays et tableaux numpy.

4

Vous devrez déterminer quelle propriété commune les entrées légales pour votre partage de fonction. Pour la première, on dirait qu'il devrait être itérable:

>>> from collections import Iterable 
>>> def fun(data: Iterable): 
...  pass 
... 
>>> isinstance(np.ndarray(0), Iterable) 
True 
>>> isinstance([], Iterable) 
True 
>>> isinstance(23, Iterable) 
False 

Pour vos têtes, il sent comme Nifti1Header et Nifti2Header devrait hériter d'une classe de base commune. Si la fonction doit fonctionner pour n'importe quelle classe dérivée, pourquoi ne pas l'annoter avec la classe de base?