python类方法怎么调用_python – 获取调用方法的类名

您可以使用

inspect.currentframe()获取调用框架对象,并通过其f_locals属性获取self绑定的对象:

import inspect

def get_some_info():

# get the call frame of the calling method

frame = inspect.currentframe().f_back

try:

# try to access the caller's "self"

try:

self_obj = frame.f_locals['self']

except KeyError:

return None

# get the class of the "self" and return its name

return type(self_obj).__name__

finally:

# make sure to clean up the frame at the end to avoid ref cycles

del frame

这样做的缺点是它依赖于第一个名为“self”的参数.在某些情况下,我们使用不同的名称,例如在编写元类时:

class MyMeta(type):

def __call__(cls, *args, **kwargs):

get_some_info() # won't work!

如果你有一个带有自变量的函数,它会产生意想不到的结果:

def not_a_method():

self = 3

print(get_some_info()) # output: int

我们可以解决这两个问题,但需要做很多工作.我们可以通过调用代码对象的co_varnames属性检查“self”参数的名称.并且为了检查调用函数是否真的是类中定义的方法,我们可以遍历self的MRO并尝试找到调用我们的方法.最终的结果是这种怪异:

def get_some_info():

# get the call frame of the calling method

frame = inspect.currentframe().f_back

try:

# find the name of the first variable in the calling

# function - which is hopefully the "self"

codeobj = frame.f_code

try:

self_name = codeobj.co_varnames[0]

except IndexError:

return None

# try to access the caller's "self"

try:

self_obj = frame.f_locals[self_name]

except KeyError:

return None

# check if the calling function is really a method

self_type = type(self_obj)

func_name = codeobj.co_name

# iterate through all classes in the MRO

for cls in self_type.__mro__:

# see if this class has a method with the name

# we're looking for

try:

method = vars(cls)[func_name]

except KeyError:

continue

# unwrap the method just in case there are any decorators

try:

method = inspect.unwrap(method)

except ValueError:

pass

# see if this is the method that called us

if getattr(method, '__code__', None) is codeobj:

return self_type.__name__

# if we didn't find a matching method, return None

return None

finally:

# make sure to clean up the frame at the end to avoid ref cycles

del frame

这应该可以处理你正确抛出的所有内容:

class Base:

def my_method(whatever):

print(get_some_info())

@functools.lru_cache() # could be any properly implemented decorator

def my_decorated_method(foo):

print(get_some_info())

@classmethod

def my_class_method(cls):

print(get_some_info())

class A(Base):

pass

def not_a_method(self=3):

print(get_some_info())

A().my_method() # prints "A"

A().my_decorated_method() # prints "A"

A.my_class_method() # prints "None"

not_a_method() # prints "None"

print(get_some_info()) # prints "None"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值