gpt4 book ai didi

python - 从帧中检测方法与哪个类关联

转载 作者:行者123 更新时间:2023-12-01 09:05:48 26 4
gpt4 key购买 nike

我正在用 Python 编写一段令人难以置信的 hackish 的不完全生产代码,我需要某种方法来检测 _XYZ__foo 是否存在。属性访问是从名为 /_*XYZ/ 的类上定义的方法调用的。 。不过,这并不那么容易,因为我需要检测原始方法访问,以防任何内容被覆盖 __getattribute__并调用super() .

我不擅长解释,所以...规则类似于Java的private ,除了我想防止作弊。 (是的,我知道这与 Python 哲学背道而驰;请耐心听我说。)

我目前的攻击计划是:

  1. 使用re.compile('_(?P<class>.*?)__(?P<name>.*)')检测类的名称(前面的 _ 被删除)。
  2. 攀爬super链条 sys._getframe(n)找出属性访问的位置。
  3. 以某种方式检测它在哪个类(class)。我被困在这里了。

我也许可以通过模拟 super 来做到这一点正在 MRO 中行走,但我更愿意依赖检测,因为检查 super 所调用的内容而用户函数调用的内容是很难的。

所以,回答我的实际问题。给定一个框架,如何检测方法与哪个类关联?如果我有权访问函数对象,我可以做 f.__qualname__[:-1-len(f.__name__)] ,但我不这样做(或者至少,我不认为我这样做)。事实上,我不知道该怎么做!

这是一个简单的示例,演示了我想要做的事情:

import sys
import re
import itertools
import builtins
from builtins import __build_class__

def build_class(func, name, *bases, metaclass=None, **kwds):
if bases[-1] is object:
bases = bases[:-1]
bases += HackishClass, object
if metaclass is None:
return __build_class__(func, name, *bases, **kwds)
return __build_class__(func, name, *bases, metaclass=metaclass, **kwds)

private_regex = re.compile('_(?P<class>.*?)__(?P<name>.*)')
class HackishClass:
__slots__ = ()
def __getattribute__(self, key):
match = private_regex.match(key)
if match is not None:
for depth in itertools.count(1):
frame = sys._getframe(depth)
if ...: # snip
# Check for the original attribute access here.
break
class_name = ... # HERE! MAGIC GOES HERE!
if class_name != match['class']:
raise AttributeError("This is private! Keep out.")
return super().__getattribute__(key)

builtins.__build_class__ = build_class

最佳答案

据我所知,没有办法直接从框架对象中获取发生属性访问的方法。但是,我们可以获得该方法的 code object 。然后我们可以搜索该对象的 MRO,直到找到该代码对象所属的方法。

private_regex = re.compile('_(?P<class>.*?)__(?P<name>.*)')
class HackishClass:
__slots__ = ()

def __getattribute__(self, key):
match = private_regex.match(key)
if match is None:
# not a private attribute, no problem
return super().__getattribute__(key)

# obtain the code object of the calling function
calling_codeobj = inspect.currentframe().f_back.f_code

# iterate the MRO until we find a class with the name from `key`
classname = match.group('class')
for cls in type(self).mro():
if cls.__name__ != classname:
continue

# check if the code object belongs to a method defined in this class
for thing in vars(cls).values():
if getattr(thing, '__code__', None) is calling_codeobj:
# found it! allow the attribute access
return super().__getattribute__(key)

raise AttributeError("This is private! Keep out.")

一个小演示:

class Foo:
def __init__(self):
self.__foo = 5
print(self.__foo)

f = Foo() # prints 5
print(f._Foo__foo) # throws AttributeError

关于python - 从帧中检测方法与哪个类关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52060860/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com