问题描述
我需要创建一个对象,该对象以任何方式使用时都会引发自定义异常UnusableObjectError
(尽管创建该对象不应创建异常).
I need to create an object that would raise a custom exception, UnusableObjectError
, when it is used in any way (creating it should not create an exception though).
a = UnusableClass() # No error
b = UnusableClass() # No error
a == 4 # Raises UnusableObjectError
'x' in a # Raises UnusableObjectError
for i in a: # Raises UnusableObjectError
print(i)
# ..and so on
我想出了下面的代码,该代码似乎表现出预期的效果.
I came up with the code below which seems to behave as expected.
class UnusableObjectError(Exception):
pass
CLASSES_WITH_MAGIC_METHODS = (str(), object, float(), dict())
# Combines all magic methods I can think of.
MAGIC_METHODS_TO_CHANGE = set()
for i in CLASSES_WITH_MAGIC_METHODS:
MAGIC_METHODS_TO_CHANGE |= set(dir(i))
MAGIC_METHODS_TO_CHANGE.add('__call__')
# __init__ and __new__ must not raise an UnusableObjectError
# otherwise it would raise error even on creation of objects.
MAGIC_METHODS_TO_CHANGE -= {'__class__', '__init__', '__new__'}
def error_func(*args, **kwargs):
"""(nearly) all magic methods will be set to this function."""
raise UnusableObjectError
class UnusableClass(object):
pass
for i in MAGIC_METHODS_TO_CHANGE:
setattr(UnusableClass, i, error_func)
问题:
是否已经存在行为符合所描述的类?
Questions:
Is there an already existing class that behaves as described?
如果没有,我的UnusableClass()
是否存在任何缺陷(例如,使用类实例的情况不会引发错误),如果是,我该如何解决这些缺陷?
If not, is there any flaw in my UnusableClass()
(e.g., situations when using the instances of the class wouldn't raise an error) and if so, how can I fix those flaws?
推荐答案
转出元类和dunder(双下划线)方法不能很好地结合在一起(不幸的是,因为那样会更简化地实现此方法) ).
Turns out metaclasses and dunder (double underscore) methods don't go well together (which is unfortunate, since that would have been a more streamlined way to implement this).
我找不到任何可导入的魔术方法名称列表,因此我创建了一个名称并将其放在PyPi上( https://pypi.python.org/pypi/magicmethods/0.1.1 ).有了它,UnusableClass的实现可以写成一个简单的类装饰器:
I couldn't find any importable listing of magic method names, so I created one and put it on PyPi (https://pypi.python.org/pypi/magicmethods/0.1.1). With it, the implementation of UnusableClass can be written as a simple class decorator:
import magicmethods
class UnusableObjectError(Exception):
pass
def unusable(cls):
def _unusable(*args, **kwargs):
raise UnusableObjectError()
for name in set(magicmethods.all) - set(magicmethods.lifecycle):
setattr(cls, name, _unusable)
return cls
@unusable
class UnusableClass(object):
pass
magicmethods.lifecycle
包含__new__
,__init__
和__del__
.您可能需要对此进行调整..
magicmethods.lifecycle
contains __new__
, __init__
, and __del__
. You might want to adjust this..
此实现还可以处理:
a = UnusableClass()
with a:
print 'oops'
这篇关于以任何方式使用都会引发异常的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!