Для каждой функции в классе в Python - PullRequest
5 голосов
/ 13 апреля 2009

В Python можно ли запустить каждую функцию внутри класса?

EDIT: Я пытаюсь вызвать функции внутри класса, собрать их возвращаемые переменные и работать с этим.

Ответы [ 6 ]

4 голосов
/ 13 апреля 2009

да, вы можете. Быстро и грязно:

class foo:
    def one(self):
        print "here is one"
    def two(self):
        print "here is two"
    def three(self):
        print "here is three"


obj = foo()
for entry in dir(obj):
    print entry, callable(getattr(obj,entry))
    if callable(getattr(obj,entry)):
        getattr(obj,entry)()

Если вы хотите более изощренную концепцию, проверьте модуль unittest.py. Должен быть код, который выполняет все методы, начинающиеся со строки «test»

3 голосов
/ 14 апреля 2009

Встроенная dir перечислит все атрибуты объекта, например:

>>> class MyClass:
...     def one(self):
...         print "one"
...     def two(self):
...         print "two"
...     def three(self):
...         print "three"
... 
>>> dir(MyClass)
['__doc__', '__module__', 'one', 'three', 'two']

Он также работает в инициализированном классе.

>>> c = MyClass()
>>> dir(c)
['__doc__', '__module__', 'one', 'three', 'two']

Методы - это просто атрибуты, которые могут вызываться (через c.attribute()) - мы можем использовать функцию getattr для ссылки на этот метод через переменную.

>>> myfunc = getattr(c, 'one')
>>> myfunc
<bound method MyClass.one of <__main__.MyClass instance at 0x7b0d0>>

Тогда мы можем просто вызвать эту переменную ..

>>> myfunc()
one # the output from the c.one() method

Поскольку некоторые атрибуты не являются функциями (в приведенном выше примере __doc__ и __module__). Мы можем использовать встроенную функцию callable , чтобы проверить, является ли она вызываемым методом (функцией):

>>> callable(c.three)
True
>>> callable(c.__doc__)
False

Итак, чтобы объединить все это в цикл:

>>> for cur_method_name in dir(c):
...     the_attr = getattr(c, cur_method_name)
...     if callable(the_attr):
...             the_attr()
... 
one
three
two

Помните, что это вызовет методы, такие как __init__ снова, что, вероятно, нежелательно. Вы можете пропустить любые cur_method_name, начинающиеся с подчеркивания

3 голосов
/ 13 апреля 2009

Зависит от того, что вы подразумеваете под «функцией». Что-то вроде этого может работать, хотя:

import inspect

def methods(c):
    return (m for m in (getattr(c, d) for d in dir(c))
            if inspect.ismethoddescriptor(m) or inspect.ismethod(m))

Тогда:

class C:
    def f(self): pass

>>> list(methods(C))
[<unbound method C.f>]
1 голос
/ 13 апреля 2009

Попробуйте использовать модуль проверки :

import inspect

class Spam:
    def eggs(self):
        print "eggs"
    def ducks(self):
        print "ducks"
    value = "value"

spam = Spam()
for name, method in inspect.getmembers(spam, callable):
    method()

Выход:

ducks
eggs
1 голос
/ 13 апреля 2009

Поскольку вы написали класс, вы уже знаете все функции.

class ThisIsPeculiar( object ):
    def aFunction( self, arg1 ):
        pass
    def anotherFunction( self, thisArg, thatArg ):
        pass
    functionsToCall = [ aFunction, anotherFunction ]

>>> p= ThisIsPeculiar()
>>> p.functionsToCall
[<function aFunction at 0x6b830>, <function anotherFunction at 0x6b870>]
1 голос
/ 13 апреля 2009

Вот тот, который использует yield для циклического перебора функций в классе.

def get_functions(mod):
    for entry in dir(mod):
        obj=getattr(mod,entry);
        if hasattr(obj, '__call__') and hasattr(obj,'__func__') :
            yield obj

class foo:
    def one(self):
        print ("here is two")
        return 1
    def two(self):
        print ("here is two")
        return 2
    def three(self):
        print ("here is three")
        return 3


print(sum([fun() for fun in get_functions(foo())]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...