使用Python3以可重用的方式获取当前方法的名称,当前实例的类名,下一个子实例的类名?

时间:2015-06-25 17:32:55

标签: python-3.x

我想提取 - “当前”方法的名称 - 当前对象/实例的类名 - 该对象/实例的下一个基类的类名

以下示例中的问题是,methode-name并不是我想要的。但我需要让这些代码可以重复使用很多类。我不想为我需要的每个类增加代码。

File to import not found or unreadable: compass/css3.

我的问题背景: 如果有人打电话给/Users/ashleighalmeida/.rbenv/shims/gem /usr/bin/gem ,我想实现一个通用的未实现错误消息。消息可能是 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys, inspect def notimpl_str(obj): classname = obj.__class__.__name__ methode = sys._getframe().f_code.co_name hi = inspect.getmro(obj.__class__) nistr = 'In {}.{}()\nLook in {}.{}()' \ .format(classname, methode, hi[1].__name__, methode) return nistr class Foo: def test(self): print(notimpl_str(self)) class Xoo(Foo): def __init__(self): self.test() Xoo()

3 个答案:

答案 0 :(得分:3)

这远非完美,但更接近于“通用”。 ;)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, inspect

def create_niestr(obj,
                  abstract_class,
                  methode):
    classname = obj.__class__.__name__
    hi = inspect.getmro(obj.__class__)
    this_method = getattr(obj, methode)
    base_method = getattr(abstract_class, methode)

    if classname is not abstract_class.__name__ and this_method.__func__ is base_method:
        nistr = 'Please implement {}.{}(). See the documentation of {}.{}() for more details.' \
                .format(classname, methode, hi[1].__name__, methode)
    else:
        nistr = 'Normal execution.'

    return nistr


class Foo:
    def test(self):
        nistr = create_niestr(self,
                              Foo,
                              sys._getframe().f_code.co_name)
        print(nistr)


class Xoo(Foo):
    pass

class Zoo(Foo):
    def test(self):
        super(self.__class__, self).test()

Foo().test()
Xoo().test()
Zoo().test()

答案 1 :(得分:1)

我认为这就是你要找的东西。我添加了一个额外的参数'继承层次结构'

import sys
import inspect

class Foo(object):
    def __init__(self):
        flag = 0
        print("Subclasses:", end=" ")
        for subclass in self.__class__.__subclasses__(): #prints the subclasses
            print(subclass.__name__, end=" ")
            flag = 1
        if flag == 0:
            print(None)
        else:
            print()
        print("Class name: ", self.__class__.__name__) #prints the class name
        print("Method name: ", sys._getframe().f_code.co_name) #prints the method name
        a = inspect.getmro(self.__class__)
        flag = 0
        print("Inheritance Hierarchy:", end=" ")
        for i in range(len(a)): #prints the inheritance hierarchy
            if not i == 0:
                print(a[(len(a)-1)-i].__name__, end=" ")
                flag = 1
        if flag == 0:
            print(None)
        else:
            print("\n")

class Xoo(Foo):
    def __init__(self):
        flag = 0
        print("Subclasses:", end=" ")
        for subclass in self.__class__.__subclasses__(): #prints the subclasses
            print(subclass.__name__, end=" ")
            flag = 1
        if flag == 0:
            print(None)
        else:
            print()
        print("Class name: ", self.__class__.__name__) #prints the class name
        print("Method name: ", sys._getframe().f_code.co_name) #prints the method name
        a = inspect.getmro(self.__class__)
        flag = 0
        print("Inheritance Hierarchy:", end=" ")
        for i in range(len(a)): #prints the inheritance hierarchy
            if not i == 0:
                print(a[(len(a)-1)-i].__name__, end=" ")
                flag = 1
        if flag == 0:
            print(None)
        else:
            print("\n")

class Zoo(Xoo):
    def __init__(self):
        flag = 0
        print("Subclasses:", end=" ")
        for subclass in self.__class__.__subclasses__(): #prints the subclasses
            print(subclass.__name__, end=" ")
            flag = 1
        if flag == 0:
            print(None)
        else:
            print()
        print("Class name: ", self.__class__.__name__) #prints the class name
        print("Method name: ", sys._getframe().f_code.co_name) #prints the method name
        a = inspect.getmro(self.__class__)
        flag = 0
        print("Inheritance Hierarchy:", end=" ")
        for i in range(len(a)): #prints the inheritance hierarchy
            if not i == 0:
                print(a[(len(a)-1)-i].__name__, end=" ")
                flag = 1
        if flag == 0:
            print(None)
        else:
            pass

Foo()
Xoo()
Zoo()

运行上述代码,您将获得以下输出

Subclasses:  Xoo
Class name:  Foo
Method name:  __init__
Inheritance Hierarchy:  Foo 

Subclasses:  Zoo
Class name:  Xoo
Method name:  __init__
Inheritance Hierarchy:  Foo Xoo 

Subclasses:  None
Class name:  Zoo
Method name:  __init__
Inheritance Hierarchy:  Foo Xoo Zoo

答案 2 :(得分:1)

看看这个!

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, inspect

class Foo:
    def test(self):
        classname = self.__class__.__name__
        methode = sys._getframe().f_code.co_name
        hi = inspect.getmro(self.__class__)
        this_method = getattr(self, 'test')
        base_method = getattr(Foo, 'test') #here 'Foo' is the base class and so this value has to be hard-coded for every base class inside which you paste this code
        if classname is not "Foo" and this_method.__func__ is base_method:
            nistr = 'Please implement {}.{}(). See the documentation of {}.{}() for more details.'\
            .format(classname, methode, hi[1].__name__, methode)
            print(nistr)
        else:
            print("Normal execution.") #put the actual code for the 'test' method here

class Xoo(Foo):
    pass

class Zoo(Foo):
    def test(self):
        super(self.__class__, self).test()

Foo().test() #test has been defined so normal execution
Xoo().test() #test has not been defined so a message is shown
Zoo().test() #test has been defined, even if it is just for calling the base class's 'test' method, it is still a valid definition so normal execution

<强>输出 -

Normal execution.
Please implement Xoo.test(). See the documentation of Foo.test() for more details.
Normal execution.

关于实现你在问题中显示的泛型方法,我会说这会产生很多混乱,甚至可能不可能,因为self的值不能包含调用对象以及被调用对象。此外,如果您调用另一种方法来检查此项,那么sys._getframe().f_code.co_name将不再返回原始方法的名称,这就是您想要的。因此,最好的方法是将这段代码添加到每个基类。