Python中的类型转换

2 投票
4 回答
3096 浏览
提问于 2025-04-16 11:16

我在Stack Overflow上看了类似的问题,但没有一个能解决我的困扰。例如,如何将一个实例转换为派生类?,但那个答案似乎并不是我想要的。

这是我的情况。我有一个像Django那样的类结构。

class Base:
     ...some stuff...

class Derived(Base):
     ...some more stuff...

现在,当我在Django中进行一些查询时,我总是得到的是基类的对象。

 baseobj = get_object_or_404(Base, id = sid)

在运行时,我也可能遇到“派生”对象,它们有一些额外的属性。我能判断一个对象是基类还是派生类(基类对象中有足够的信息)。但是,我该如何访问那些只在派生类中存在的额外字段呢?我无法将“基类”转换为“派生类”。我该怎么处理这个问题呢?

编辑:

我找到了问题所在。Django将派生类的“附加属性”存储在一个单独的表中。因此,问题出在这一行代码上。

baseobj = get_object_or_404(Base, id = sid)

baseobj将始终是基类的对象,并且不会拥有派生类的任何属性。我需要进行额外的查询才能获取派生类的对象。

baseobj = get_object_or_404(Base, id = sid)
if baseobj.isDerivedType:
      derivedobj = get_object_or_404(Derived, id = sid)

4 个回答

1

我在Python中从来没有遇到过这种情况。感觉这有点不太对劲,你有一个类型的实例,却需要知道这个对象的最具体类型。其实你应该根据你使用的函数就知道这个类型是什么。也许如果你能给我们看看你实际使用的代码,我们能帮你找到更好的解决办法。

检查你的对象是否是某种派生类型的问题在于,当你添加另一个派生类时,你就得修改你的基类来检查这个新派生类型。这会破坏面向对象编程的原则。如果其他人使用你的代码,他们如果想从你的类派生,就会变得很麻烦。

尽量多使用派生类型。Django中继承的意义在于允许代码重用和类之间共享数据,而不是隐藏信息。

2

通常,我会说在这种情况下使用try-except语句是很常见的做法。

class thing1(object):
    def __init__(self):
        self.a = 5

class thing2(thing1):
    def __init__(self):
        super(thing2, self).__init__()
        self.b = 6

t = thing1()
try: 
    print(t.b)
except AttributeError: 
    print("handling the exception")

补充:不过,我是不是理解错了你的问题?答案是:不对。哎呀!

补充2:尽管如此,看起来在上面的try-except代码块上做一些改动,应该比像你修改后的问题那样访问数据库两次要好。

9

在Django这个框架里,这种继承方式让我想到了多表继承。根据文档,如果一切设置得当,你应该可以这样做:

baseobj.derived    # note: small 'd'

撰写回答