Определить порядок объявления функций Python / IronPython - PullRequest
3 голосов
/ 24 сентября 2010

Я пытаюсь взять класс python (в IronPython), применить его к некоторым данным и отобразить в виде сетки.Результаты функций становятся столбцами в сетке, и я хотел бы, чтобы порядок функций был порядком столбцов.Есть ли способ определить порядок функций Python класса в порядке, они были объявлены в исходном коде?Я возьму ответы, которые используют либо IronPython, либо обычный python.

Так, например, если у меня есть класс:

class foo:
    def c(self):
        return 3
    def a(self):
        return 2
    def b(self):
        return 1

Я бы хотел (без разбора исходного кода сам)вернуть список [c, a, b].Есть идеи?

В качестве предостережения IronPython использовал ссылки на функции в том порядке, в котором они их объявили.В .NET 4 они изменили это поведение, чтобы соответствовать python (который всегда перечисляет их в алфавитном порядке).

Ответы [ 3 ]

2 голосов
/ 24 сентября 2010

Почему вы не можете разобрать код самостоятельно?Это просто:

import inspect
import ast

class Foo:
    def c(self):
        pass

    def a(self):
        pass

    def b(self):
        pass

code = ast.parse(inspect.getsource(Foo))

class FunctionVisitor(ast.NodeVisitor):
    def visit_FunctionDef(self, node):
        print(node.name)

FunctionVisitor().visit(code)

выходы

c
a
b
2 голосов
/ 24 сентября 2010

В Python 2.X (IronPython в настоящее время работает на Python 2), к сожалению, нет.Python создает словарь членов класса перед созданием объекта класса.После создания класса не существует «записи» порядка .

. В Python 3 улучшены метаклассы (которые используются для создания классов), и вы можете использовать пользовательский объект вместостандартный словарь для сбора членов класса по мере создания класса.Это позволяет вам узнать порядок.

Однако для IronPython есть способ, который может работать.Словари Python по своей природе неупорядочены - т.е. перебор членов словаря возвращает их в произвольном (но стабильном) порядке.В IronPython использовался для случая, когда при случайной реализации итерация возвращала элементы в порядке их вставки.(Обратите внимание, что это больше не может иметь место.)

Вы можете попробовать:

 members = list(c.__dict__) # or c.__dict__.keys()

Вы можете обнаружить, что это заказано, как вы надеетесь.К сожалению, выполнение кода под разными версиями IronPython (или других реализаций Python), вероятно, вернет их в другом порядке.

Другой (лучше, но сложнее) подход заключается в использовании модуля ast (или парсера IronPython)) и пройти AST, чтобы найти записи.Не очень сложно, но больше работы.

1 голос
/ 24 сентября 2010

Другое решение - использовать декоратор для добавления их в список.

def make_registry():
    def register(f):
        register.funcs.append(f)
        return f
    register.funcs = []
    return register

register = make_registery()

class Foo(object):

    @register
    def one(self):
        pass

    @register
    def two(self):
        pass

    @register
    def three(self):
        pass

    def utility_method_that_shouldnt_be_run_in_the_sequence(self):
        pass

print register.funcs
...