Как уже упоминали другие, это действительно сложный вопрос. Решения для этого не «один размер подходит всем», даже удаленно. Трудность (или легкость) действительно будет зависеть от вашей ситуации.
Я сталкивался с этой проблемой несколько раз, но совсем недавно, когда создавал функцию отладки. Я хотел, чтобы функция принимала некоторые неизвестные объекты в качестве аргументов и печатала их объявленные имена и содержимое. Получить содержимое, конечно, легко, но объявленное имя - другая история.
Ниже следует кое-что из того, что я придумал.
Возвращаемое имя функции
Определить имя функции очень просто, поскольку она имеет атрибут __ name __ , содержащий объявленное имя функции.
name_of_function = lambda x : x.__name__
def name_of_function(arg):
try:
return arg.__name__
except AttributeError:
pass`
В качестве примера, если вы создадите функцию def test_function(): pass
, затем copy_function = test_function
, а затем name_of_function(copy_function)
, она вернет test_function .
Возвращает первое совпадающее имя объекта
Проверьте, имеет ли объект атрибут __name __ и верните его, если так (только объявленные функции). Обратите внимание, что вы можете удалить этот тест, так как имя все еще будет в globals()
.
Сравните значение arg со значениями элементов в globals()
и верните имя первого совпадения. Обратите внимание, что я отфильтровываю имена, начинающиеся с '_'.
Результат будет состоять из имени первого соответствующего объекта, в противном случае None.
def name_of_object(arg):
# check __name__ attribute (functions)
try:
return arg.__name__
except AttributeError:
pass
for name, value in globals().items():
if value is arg and not name.startswith('_'):
return name
Вернуть все соответствующие имена объектов
- Сравните значение arg со значениями элементов в
globals()
и сохраните имена в списке. Обратите внимание, что я отфильтровываю имена, начинающиеся с '_'.
Результат будет состоять из списка (для нескольких совпадений), строки (для одного совпадения), в противном случае - Нет. Конечно, вы должны настроить это поведение по мере необходимости.
def names_of_object(arg):
results = [n for n, v in globals().items() if v is arg and not n.startswith('_')]
return results[0] if len(results) is 1 else results if results else None