当通过传递的对象调用不同的方法时,isinstance的使用是否合理

2024-09-27 21:26:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个小工具,它能够读取文件的底层数据,如映射等,并使用python内置的sqliteapi将结果存储到sqlitedb。你知道吗

对于解析的文件数据,我有3个类:

class GenericFile: # general file class 
    # bunch of methods here
    ...
class SomeFileObject_A: # low level class for storing objects of kind SomeFileObject_A
    # bunch of methods here
    ...
class SomeFileObject_B: # low level cass for storing objects of kind SomeFileObject_A
    # bunch of methods here
    ...

sqlite接口作为一个单独的类实现:

class Database:
    def insert(self, object_to_insert):
    ...
    def _insert_generic_file_object(self, object_to_insert):
    ...
    def _insert_file_object_a(self, object_to_insert):
    ...
    def _insert_file_object_b(self, object_to_insert):
    ...
    # bunch of sqlite related methods

当我需要向DB插入一些对象时,我使用的是db.insert(object)。你知道吗

现在我认为在我的insert方法中使用isinstance是个好主意,因为它处理任何插入的对象,而不需要显式地为每个对象调用合适的方法,这样看起来更优雅。 但是在阅读了更多关于isinstance的文章之后,我开始怀疑,我的设计不是很好。你知道吗

下面是泛型insert方法的实现:

class Database:
    def insert(self, object_to_insert):
        self._logger.info("inserting %s object", object_to_insert.__class__.__name__)
        if isinstance(object_to_insert, GenericFile):
            self._insert_generic_file_object(object_to_insert)
        elif isinstance(object_to_insert, SomeFileObject_A):
            self._insert_file_object_a(object_to_insert)
        elif isinstance(object_to_insert, SomeFileObject_B):
            self._insert_file_object_b(object_to_insert)
        else:
            self._logger.error("Insert Failed. Bad object type %s" % type(object_to_insert))
            raise Exception
        self._db_connection.commit()

所以,在我的例子中应该避免isinstace,如果应该,这里有什么更好的解决方案?你知道吗

谢谢


Tags: ofto对象方法selfhereobjectdef
1条回答
网友
1楼 · 发布于 2024-09-27 21:26:57

OO的基本原则之一是用多态分派代替显式开关。在您的例子中,解决方案是使用双重分派,因此FileObect负责知道调用哪个Database方法,即:

class GenericFile: # general file class 
    # bunch of methods here
    ...
    def insert(self, db):
        return db.insert_generic_file_object(self)


class SomeFileObject_A: # low level class for storing objects of kind SomeFileObject_A
    # bunch of methods here
    ...
    def insert(self, db):
        return db.insert_file_object_a(self)


class SomeFileObject_B: # low level cass for storing objects of kind SomeFileObject_A
    # bunch of methods here
    ...
    def insert(self, db):
        return db.insert_file_object_b(self)


class Database:
    def insert(self, obj):
        return obj.insert(self)

相关问题 更多 >

    热门问题