- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
A 类型的对象以及是否有一种方法可以通过编程方式包装类对象?
给定
class A(object):
def __init__(self):
## ..
def f0(self, a):
## ...
def f1(self, a, b):
## ..
我想要另一个包装 A 的类,例如
class B(object):
def __init__(self):
self.a = A()
def f0(self,a):
try:
a.f0(a)
except (Exception),ex:
## ...
def f1(self, a, b):
try:
a.f1(a,b)
except (Exception),ex:
## ...
有没有办法通过反射/检查类 A
来创建 B.f0
& B.f1
?
最佳答案
如果你想通过调用预定义类 A
上的函数来创建类 B
,你可以简单地执行 B = wrap_class(A)
带有如下所示的函数 wrap_class
:
import copy
def wrap_class(cls):
'Wraps a class so that exceptions in its methods are caught.'
# The copy is necessary so that mutable class attributes are not
# shared between the old class cls and the new class:
new_cls = copy.deepcopy(cls)
# vars() is used instead of dir() so that the attributes of base classes
# are not modified, but one might want to use dir() instead:
for (attr_name, value) in vars(cls).items():
if isinstance(value, types.FunctionType):
setattr(new_cls, attr_name, func_wrapper(value))
return new_cls
B = wrap_class(A)
正如 Jürgen 所指出的,这会创建一个类的副本;但是,只有在您真的想保留原始类 A
时才需要这样做(如原始问题中所建议的那样)。如果你不关心 A
,你可以简单地用一个不执行任何复制的包装器来装饰它,就像这样:
def wrap_class(cls):
'Wraps a class so that exceptions in its methods are caught.'
# vars() is used instead of dir() so that the attributes of base classes
# are not modified, but one might want to use dir() instead:
for (attr_name, value) in vars(cls).items():
if isinstance(value, types.FunctionType):
setattr(cls, attr_name, func_wrapper(value))
return cls
@wrap_class
class A(object):
… # Original A class, with methods that are not wrapped with exception catching
装饰类 A
捕获异常。
元类版本比较重,但原理类似:
import types
def func_wrapper(f):
'Returns a version of function f that prints an error message if an exception is raised.'
def wrapped_f(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception, ex:
print "Function", f, "raised", ex
return wrapped_f
class ExceptionCatcher(type):
'Metaclass that wraps methods with func_wrapper().'
def __new__(meta, cname, bases, cdict):
# cdict contains the attributes of class cname:
for (attr_name, value) in cdict.items():
if isinstance(value, types.FunctionType): # Various attribute types can be wrapped differently
cdict[attr_name] = func_wrapper(value)
return super(meta, ExceptionCatcher).__new__(meta, cname, bases, cdict)
class B(object):
__metaclass__ = ExceptionCatcher # ExceptionCatcher will be used for creating class A
class_attr = 42 # Will not be wrapped
def __init__(self):
pass
def f0(self, a):
return a*10
def f1(self, a, b):
1/0 # Raises a division by zero exception!
# Test:
b = B()
print b.f0(3.14)
print b.class_attr
print b.f1(2, 3)
这打印:
31.4
42
Function <function f1 at 0x107812d70> raised integer division or modulo by zero
None
你想做的实际上通常是由一个元类完成的,元类是一个类,其实例是一个类:这是一种基于其解析的 Python 代码动态构建 B
类的方法(类 A
的代码,在问题中)。有关这方面的更多信息,请参阅 Chris 的 Wiki(在 part 1 和 parts 2-4 中)对元类的简短描述。
关于Python 自省(introspection) : Automatic wrapping of methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7589208/
尝试发布到 introspect 方法会引发错误的请求错误: "Bad request. Accept and/or Content-Type headers likely do not match
我想对我使用或过度使用的常用技术进行现代化改造。它静态检查方法签名并调用方法(如果存在)。我的方法比 C++17 早了一段时间 FWIW。 目前,我使用了 Boost 的 Type 特征,例如 BOO
java.beans.Introspector#getBeanInfo 将 getter 返回类型更改为 com.google.common.base.Optional 时,编译不完整的 Proper
我正在将一些“旧的”Swift 代码转换为 Swift 2.0,但我遇到了一个我无法摆脱的错误。 我的函数接收一个类型(任意)的数组,并返回一个相同类型的新数组。 此代码在 Swift 2.0 中不再
我想做的是从 SqlAlchemy 实体定义中获取所有 Column() 的内容,确定它们的类型和约束,以便能够预验证、转换数据并向用户显示自定义表单。 我如何反省它? 例子: class Perso
下面的代码是一个可以轻松重现问题的小示例。所以我有 String 类型的变量,在其上设置了默认值。我有 3 种方法: setter/getter 二传手 将字符串转换为 boolean 值的便捷方法
初级 JavaScript 问题。我有点被 Python 的 dir 内置函数宠坏了。我想发现 node.js REPL 中任何对象的属性/方法。我已经看过this question ;在空数组 []
当我使用自省(introspection)时,我的类、方法和属性名称以纯文本形式编写。就像在这个简短的演示中一样: import java.lang.reflect.Constructor; impo
我正在编写一个通用方法,该方法复制具有公共(public)字段的两种不同类型的 bean。我正在使用内省(introspection)来获取写入和读取方法,例如 propertyDescriptor1
C++ 中是否有像 python 中那样的内省(introspection)技术? 例如:我想获得有关特定对象的更多信息,而无需通过头文件或返回引用 cpp 引用。 我是在问一个正确的问题,还是走错了
我有一个函数: # utils.py def hello(name='World'): # Detect where I'm being called from. print('Hi,
我正在编写一个小的 sqlalchemy shim 以通过一些轻量级数据转换从 MySQL 数据库中导出数据——主要是更改字段名称。我当前的脚本工作正常,但需要我基本上描述我的模型两次——一次在类声明
是否有办法确定实例最初绑定(bind)到的变量? 使用函数我们可以做到这一点: def f(): pass print f.__name__ >> f g = f print g.__name
我正在为使用内省(introspection)的代码块编写单元测试;具体来说,它在我想要模拟的类上调用 getDeclaredField() 并尝试获取该字段的值。有没有办法用 Mockito 来模拟
如何在 gdbus 自省(introspection) xml 中传递多个完整类型。例子, 当我尝试这种格式时,我得到的错误是 Error org.fr
A 类型的对象以及是否有一种方法可以通过编程方式包装类对象? 给定 class A(object): def __init__(self): ## .. def f0(
我有一个需要来自测试函数的变量的 fixture 。如果函数级别的自省(introspection)有效,那么使用自省(introspection)并在函数命名空间/上下文中声明变量应该有效,就像在模
当我尝试使用内省(introspection)来查看 threading.Lock 上可用的方法时,我没有看到我期望的结果。 具体来说,我没有看到获取、释放或锁定。这是为什么? 这是我所看到的: >>
我刚刚在一个项目中发现一些测试方法没有所需的“test_”前缀来确保它们实际运行。应该可以通过一些 linting 来避免这种情况: 在代码库中查找所有 TestCase 断言调用。 在调用层次结构中
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我是一名优秀的程序员,十分优秀!