Python中的类型转换
我在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 个回答
我在Python中从来没有遇到过这种情况。感觉这有点不太对劲,你有一个类型的实例,却需要知道这个对象的最具体类型。其实你应该根据你使用的函数就知道这个类型是什么。也许如果你能给我们看看你实际使用的代码,我们能帮你找到更好的解决办法。
检查你的对象是否是某种派生类型的问题在于,当你添加另一个派生类时,你就得修改你的基类来检查这个新派生类型。这会破坏面向对象编程的原则。如果其他人使用你的代码,他们如果想从你的类派生,就会变得很麻烦。
尽量多使用派生类型。Django中继承的意义在于允许代码重用和类之间共享数据,而不是隐藏信息。
通常,我会说在这种情况下使用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代码块上做一些改动,应该比像你修改后的问题那样访问数据库两次要好。
在Django这个框架里,这种继承方式让我想到了多表继承。根据文档,如果一切设置得当,你应该可以这样做:
baseobj.derived # note: small 'd'