имя класса, содержащего код метода

Вы можете вывести использование псевдонимов из исходного кода.

console.log($.fn.delegate);
function (a, b, c, d) {
    return this.on(b, a, c, d);
}

console.log($.fn.bind);
function (a, b, c) {
    return this.on(a, null, b, c);
}

Документация также содержит примеры использования:

$(elements).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(elements).on(events, selector, data, handler);        // jQuery 1.7+

11
задан SilentGhost 6 May 2010 в 14:19
поделиться

5 ответов

В Python 3.x вы можете просто использовать __ class __.__ name __ . Имя __ class __ слегка магическое, а не то же самое, что атрибут __ class __ для self .

В Python 2.x нет хорошего способа получить эту информацию. Вы можете использовать проверку стека, чтобы получить объект кода, а затем пройтись по иерархии классов в поисках правильного метода, но это медленно и утомительно и, вероятно, сломается, когда вы этого не захотите. Вы также можете использовать метакласс или декоратор класса для некоторой постобработки класса, но оба эти подхода довольно навязчивы. И вы можете сделать что-то действительно уродливое, например получить доступ к self .__ nonexistant_attribute , перехватить AttributeError и извлечь имя класса из искаженного имени. Ни один из этих подходов не стоит того, если вы просто не хотите вводить имя дважды; по крайней мере, если вы забыли обновить имя, это можно сделать более очевидным, выполнив что-то вроде:

class C:
    ...
    def report_name(self):
        print C.__name__
7
ответ дан 3 December 2019 в 08:03
поделиться

Вы можете использовать (злоупотреблять?) манглинг частных имен для достижения этого эффекта. Если вы ищете атрибут self, который начинается с __ внутри метода, python изменит имя с __attribute на _classThisMethodWasDefinedIn__attribute.

Просто каким-то образом спрячьте нужное вам имя класса в искаженном виде там, где метод сможет его увидеть. В качестве примера, мы можем определить __new__ метод на базовом классе, который делает это:

def mangle(cls, attrname):
    if not attrname.startswith('__'):
        raise ValueError('attrname must start with __')
    return '_%s%s' % (cls.__name__, attrname)

class A(object):

    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls)
        for c in cls.mro():
            setattr(obj, mangle(c, '__defn_classname'), c.__name__)
        return obj

    def __init__(self):
        pass

    def test(self):
        print self.__defn_classname

class B(A):

    def __init__(self):
        A.__init__(self)



a = A()
b = B()

a.test()
b.test()

который печатает:

A
A
2
ответ дан 3 December 2019 в 08:03
поделиться

inspect.getmro дает вам по порядку кортеж классов, из которых может быть получен метод. Как только вы найдете один из них, у которого есть имя метода в его dict , все готово:

for c in inspect.getmro(self.__class__):
    if 'test' in vars(c): break
return c.__name__
4
ответ дан 3 December 2019 в 08:03
поделиться

Использование __dict__ самого объекта класса:

class A(object):
    def foo(self):
        pass

class B(A):
    pass

def find_decl_class(cls, method):
    if method in cls.__dict__:
        return cls
    for b in cls.__bases__:
        decl = find_decl_class(b, method)
        if decl:
            return decl

print 'foo' in A.__dict__
print 'foo' in B.__dict__
print find_decl_class(B, 'foo').__name__

Выведет True, False, A

2
ответ дан 3 December 2019 в 08:03
поделиться

Вы можете сделать

>>> class A(object):
...   def __init__(self):
...     pass
...   def test(self):
...     for b in self.__class__.__bases__:
...       if hasattr(b, 'test'):
...         return b.__name__
...     return self.__class__.__name__
... 
>>> class B(A):
...   def __init__(self):
...     A.__init__(self)
...
>>> B().test()
'A'
>>> A().test()
'A'
>>> 

Имейте в виду, что вы можете упростить это, используя __class__.__base__, но если вы используете множественное наследование, эта версия будет работать лучше.

Он просто проверяет сначала свои базовые классы на test. Это не самый красивый вариант, но он работает.

0
ответ дан 3 December 2019 в 08:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: