¿Cómo puedo iterar a través de todas las funciones en un módulo específico desde mi lugar de ejecución actual?

Aquí hay algunos detalles sobre lo que he hecho hasta ahora:

He creado un paquete llamado "test_cases" que tiene un módulo, "test_cases" que contiene docenas de funciones. Me gustaría crear algún tipo de bucle que ejecute todas las funciones en el módulo test_case.

Debajo de la primera línea en main() está test_cases.test_cases.tc_1(), esto es solo para probar que mi script puede invocar una función específica y funciona. Es el aspecto de "bucle" lo que me está preocupando.

Aquí está la idea aproximada de mi código:

def main():
    # test_cases.test_cases.tc_1()
    for _, test in test_cases.test_cases:
        test

He leído esta publicación pero la respuesta sugiere usar {{ X0}} sin embargo, iteritems() no es un atributo de __dict__ en Python 3.8 de acuerdo con PEP 469 (suponiendo que lo haya leído bien). También he leído esta publicación pero es Todavía no está claro. Así que estoy un poco perplejo sobre qué hacer.

Estoy ejecutando Windows 10, PyCharm2020.1.2, Python 3.8

EDITAR 1

Aquí está mi nueva función main() con items() utilizada como iterador. Al depurar, parece pasar por los elementos __name__, __doc__, __package__ etc. (¿cómo se llaman?) De mi módulo test_case. Luego identifica mi función, tc_1 e intenta ejecutarla, pero no sucede nada. Esperaría que ejecute la declaración print(). He adjuntado mi función a continuación para referencia. ¿Que está pasando aqui?

def main():
    for name, test in test_cases.test_cases.__dict__.items():
        if callable(test):
            test

# tc_1 is in the test_cases module 
def tc_1():
    print("TEST CASE ONE EXECUTED")

EDITAR 2

El último problema no incluía el paréntesis después de test. Una vez que esto se corrigió, el bucle funciona como se esperaba. Aquí está el código de referencia:

def main():
    for name, test in test_cases.test_cases.__dict__.items():
        if callable(test):
            test()
0
Tim51 25 jun. 2020 a las 23:32

2 respuestas

La mejor respuesta

En python 3 los diccionarios tienen un método .items(). Creo que .iteritems() es específico de Python 2. Una prueba simple de los métodos disponibles en python 3:

>>>test = {}
>>>dir(test)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
0
Reedinationer 25 jun. 2020 a las 20:42

¿Has intentado usar la función getattr ()? Puede combinarlo con la lista filtrada de módulos como mencionó @Reedinator

Aquí hay un ejemplo de cómo podría usarse:

# mymodule.py
def func_A():
    return "Hello this is function A!"


def func_B():
    return "Function B is counting bottles on the wall ..."


def func_C():
    return "Function C ... well let's see ..."

# in python shell
>>> import mymodule
>>> lst = [x for x in dir(mymodule) if not x.startswith('__')]
>>> print(lst)
['func_A', 'func_B', 'func_C']

>>> for f in lst:
...     el = getattr(mymodule, f)
...     el()
... 
'Hello this is function A!'
'Function B is counting bottles on the wall ...'
"Function C ... well let's see ..."
0
Fadi 25 jun. 2020 a las 21:04