Python中类体内的类名
在类的定义内部,能不能获取到类的名字呢?
比如说,
class Foo():
x = magic() # x should now be 'Foo'
我知道我可以在类的外面,用一个类方法静态地获取这个名字:
class Bar():
@classmethod
def magic(cls):
print cls.__name__
Bar.magic()
但是我想要的不是这个,我想在类的内部获取类的名字。
5 个回答
2
这里有一个适合你特定情况的解决方案,但要注意(我写这个主要是为了展示确实可以做到这样的事情):
- 你不应该使用它
- 它非常具体
- 有很多限制
- 我只是玩得开心
- 这有点像黑魔法
- 可能不适合你的使用场景
- 它不是线程安全的
- 我是不是已经说过你不应该使用它了?
无论如何,这里是代码:
import inspect
def NameAwareClassType():
frameInfo = inspect.getouterframes(inspect.currentframe())[1]
codeContext = frameInfo[4][0]
className = codeContext.split(' ', 1)[1].split('(', 1)[0]
class ClassNameGlobalRemoverType(type):
def __new__(mcs, name, bases, dict):
if name == className:
del globals()['__clsname__']
return type.__new__(mcs, name, bases, dict)
class NameAwareClass(object):
__metaclass__ = ClassNameGlobalRemoverType
globals()['__clsname__'] = className
return NameAwareClass
class A(NameAwareClassType()):
print __clsname__
def __init__(self):
pass
print __clsname__
编辑: https://gist.github.com/1085475 — 这里有一个版本,允许在方法执行期间使用 __clsname__
;这没什么太大意义,因为 self.__class__.__name__
是更好的方法,而且 __clsname__
变量不再保存字符串(我在这方面玩得很开心)
4
据我所知,类对象在类定义“执行”之前是不可用的,所以在定义类的时候无法获取它。
如果你需要在之后使用类名,但在定义类的时候不想用它(比如说用来计算其他字段名之类的),那么你可以通过使用类装饰器来自动化这个过程。
def classname ( field ):
def decorator ( klass ):
setattr(klass, field, klass.__name__)
return klass
return decorator
(注意:未经过测试。)
通过这个定义,你可以得到类似这样的东西:
@classname(field='x')
class Foo:
pass
这样你就可以得到字段 x
,里面包含类名,如下所示:
print Foo.x
8
好的,我再提供一个解决方案,这个其实并不复杂!
import traceback
def magic():
return traceback.extract_stack()[-2][2]
class Something(object):
print magic()
它会输出“Something”。我不太确定提取的堆栈格式是否有标准,但它在python 2.6(还有2.7和3.1)中是有效的。