首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >确定Python类是抽象基类还是具体类

确定Python类是抽象基类还是具体类
EN

Stack Overflow用户
提问于 2013-01-19 11:38:36
回答 2查看 11.8K关注 0票数 39

我的Python应用程序包含许多抽象类和实现。例如:

代码语言:javascript
复制
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是一个我们可以使用的具体类。

代码语言:javascript
复制
FriendlyMessagePrinter().greet()
代码语言:javascript
复制
Good night.

...but、MessageDisplayFriendlyMessageDisplay是抽象类,尝试实例化它们会导致错误:

代码语言:javascript
复制
TypeError: Can't instantiate abstract class MessageDisplay with abstract methods say

如何检查给定的类对象是否是(不可实例化的)抽象类?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-19 11:54:18

代码语言:javascript
复制
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,因此它不会像您的实现那样容易被欺骗:

代码语言:javascript
复制
class Fake:
    __abstractmethods__ = 'bluh'

print(is_abstract(Fake), inspect.isabstract(Fake)) # True, False
票数 49
EN

Stack Overflow用户

发布于 2013-01-19 12:05:49

您可以使用_ast模块来实现这一点。例如,如果您的示例代码是用foo.py编写的,那么您可以使用"foo.py""FriendlyMessagePrinter"作为参数来调用此函数。

代码语言:javascript
复制
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)
票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14410860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档