我的Python应用程序包含许多抽象类和实现。例如:
import abc
import datetime
class MessageDisplay(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def display(self, message):
pass
class FriendlyMessageDisplay(MessageDisplay):
def greet(self):
hour = datetime.datetime.now().timetuple().tm_hour
if hour < 7:
raise Exception("Cannot greet while asleep.")
elif hour < 12:
self.display("Good morning!")
elif hour < 18:
self.display("Good afternoon!")
elif hour < 20:
self.display("Good evening!")
else:
self.display("Good night.")
class FriendlyMessagePrinter(FriendlyMessageDisplay):
def display(self, message):
print(message)
FriendlyMessagePrinter
是一个我们可以使用的具体类。
FriendlyMessagePrinter().greet()
Good night.
...but、MessageDisplay
和FriendlyMessageDisplay
是抽象类,尝试实例化它们会导致错误:
TypeError: Can't instantiate abstract class MessageDisplay with abstract methods say
如何检查给定的类对象是否是(不可实例化的)抽象类?
发布于 2013-01-19 11:54:18
import inspect
print(inspect.isabstract(object)) # False
print(inspect.isabstract(MessageDisplay)) # True
print(inspect.isabstract(FriendlyMessageDisplay)) # True
print(inspect.isabstract(FriendlyMessagePrinter)) # False
这将检查是否在类对象中设置了内部标志TPFLAGS_IS_ABSTRACT
,因此它不会像您的实现那样容易被欺骗:
class Fake:
__abstractmethods__ = 'bluh'
print(is_abstract(Fake), inspect.isabstract(Fake)) # True, False
发布于 2013-01-19 12:05:49
您可以使用_ast
模块来实现这一点。例如,如果您的示例代码是用foo.py
编写的,那么您可以使用"foo.py"
和"FriendlyMessagePrinter"
作为参数来调用此函数。
def is_abstract(filepath, class_name):
astnode = compile(open(filename).read(), filename, 'exec', _ast.PyCF_ONLY_AST)
for node in astnode.body:
if isinstance(node, _ast.ClassDef) and node.name == class_name:
for funcdef in node.body:
if isinstance(funcdef, _ast.FunctionDef):
if any(not isinstance(n, _ast.Pass) for n in funcdef.body):
return False
return True
print 'class %s not found in file %s' %(class_name, filepath)
https://stackoverflow.com/questions/14410860
复制相似问题