Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 11, 2010 10:37:48

axe
От:
Зарегистрирован: 2008-08-07
Сообщения: 256
Репутация: +  0  -
Профиль   Отправить e-mail  

имя текущего исполняемого метода

внутри класса можно узнать название текущего класса:

class myClass(object):
def __init__(self):
print self.__class__.__name__
myClass()
выведет “myClass”

можно ли узнать имя текущего метода? (т.е. получить “__init__” или другое название)



Офлайн

#2 Янв. 11, 2010 14:43:45

bobry
От:
Зарегистрирован: 2008-08-03
Сообщения: 54
Репутация: +  0  -
Профиль   Отправить e-mail  

имя текущего исполняемого метода

можно, где то оно во фрейме закопано, вам вот сюдa



Офлайн

#3 Янв. 11, 2010 15:58:33

expee
От:
Зарегистрирован: 2009-12-21
Сообщения: 197
Репутация: +  0  -
Профиль   Отправить e-mail  

имя текущего исполняемого метода

C mail.python.org:

>>> def get_called_name(depth=0):
... return sys._getframe(depth + 1).f_code.co_name
...
>>> class Hello:
... def __init__(self):
... print get_called_name()
...
>>> h = Hello()
__init__
>>>



Офлайн

#4 Янв. 11, 2010 17:17:03

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

имя текущего исполняемого метода

К сожалению, не совсем верно.
Получается имя codeobject, а не function. По умолчанию они совпадают - питон делает их одинаковыми при создании.
Добраться из codeobject до function невозможно. Я делал это спец декоратором, который в globals() перед вызовом вставлял свои имена - и их можно было видеть внутри функции.

Короткая иллюстрация проблемы:

>>> class A(object):
... pass
...
>>> def f(self):
... return sys._getframe().f_code.co_name
...
>>> A.g = f
>>> a = A()
>>> a.g()
'f'



Офлайн

#5 Янв. 12, 2010 17:07:56

ofigetitelno
От:
Зарегистрирован: 2006-08-01
Сообщения: 136
Репутация: +  0  -
Профиль   Отправить e-mail  

имя текущего исполняемого метода

:)
можно попробовать так:

from new import function, instancemethod
from byteplay import Code, LOAD_CONST, STORE_FAST
from types import MethodType

class A(object):
def __getattribute__(self, name):
attr = super(A, self).__getattribute__(name)
if type(attr) is MethodType and not hasattr(attr.im_func, '_patched'):
c = Code.from_code(attr.func_code)
c.code[0:0] = [
(LOAD_CONST, name),
(STORE_FAST, '_func_name')]
f = function(c.to_code(), globals(), attr.__name__)
f._patched = True
attr = instancemethod(f, self, A)
setattr(self, name, attr)
return attr

def zzz(self):
print locals().get('_func_name')

def f(self):
print locals().get('_func_name')

A.g = f
a = A()
a.zzz()
a.zzz()
a.g()



Офлайн

#6 Янв. 12, 2010 17:54:01

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

имя текущего исполняемого метода

Юра, примерно это я и делал в одной из версий своего декоратора.
Только использовал peak BytecodeAssembler. Если скорость не критична - globals выглядят чуть проще и меньше пугают народ :). Правда нужно было постоянно добавлять/удалять свое имя, что не очень красиво.

Похоже, при желании можно также заменить __getattribute__ на metaclass.

Собственно было интересно не столько само “правильное имя” сколько прочие custom значения из __dict__ функции (Удобный контейнер для всяких настроек).
И, к сожалению, получить этот __dict__ из code object (или сам function object) нельзя.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version