【发布时间】:2018-05-15 00:05:36
【问题描述】:
我正在尝试检查我实例化的对象是否基本上实例化了子对象,以便我可以依次继续这种方式,直到我完成检查/错误检查输入/填充我的对象。目标是在不知道属性是什么的情况下填充该对象的信息,因为它们是由其他代码自动生成的,因此它们可能会发生更改,恕不另行通知。我正在尝试使用递归函数来做到这一点。举个例子可能会更清楚一点:
### content of B.py:
class B:
def __init__(self):
self.Ba = ''
self.Bb = 0
### content of A.py
from B import B
class A:
def __init__(self):
self.B = B()
self.Aa = ''
self.Ab = False
### content of SDK.py
from A import A
primitiveTypes = (int, str, bool, type(None))
class G:
def createIt(self, **options)
fillMe = A()
fillMe = self.fillWithData(fillMe, options)
#Do stuff with fillMe (post in JSON format to REST API...)
def fillWithData(self, obj, options)
for a in dir(obj):
if not callable(a) and not a.startswith('_'):
if isinstance(a, primitiveTypes):
obj.__dict__.update({a: options.get(a)})
else:
#This never gets executed because isinstance always returns true -> because it evaluates A.B as type string instead of being of type B
obj.__dict__.update({a: self.fillWithData(a, options)})
### content of test.py
from SDK import G
g = G()
g.createIt(Aa='Aa', Ab=True, Ba='Ba', Bb=1) #Make correct input succeed
g.createIt(Aa=1, Ab='', Ba=None, Bb=False) #Make incorrect input fail
编辑:我删除了退货声明,感谢您消除了我的疑虑。
解释为什么我需要所有这些不同的文件;我目前正在编写一个 SDK,以便人们可以使用它与 REST API 交互(创建用户、登录、添加内容、修改内容、删除内容 - 角色、权限等内容)所以我们有代码C# 定义模型和枚举(无方法),由代码生成器转换为 python。在上面的示例中,模型将是 A.py 和 B.py。我将它们导入 SDK (G.py),所以我有 test.py 来使用 SDK 方法。
所以问题是:isinstance 总是返回 true - 因为它认为对象 b 是 String 类型,而实际上它应该是 B 类型。
【问题讨论】:
-
您不需要
G.fillWithData()中的return obj,因为您对返回值所做的只是将其分配给G.creatIt()中名为fillMe的局部变量,这与它(所以它被丢弃了)。在您问题的最后两行代码中,尚不清楚其中一个是正确的,而另一个是正确的。请edit您提出问题并描述每种情况下结果的正确性和错误性。 -
@martineau 实际上,
self.fillWithData(a, options)}被递归调用,并且返回值将在fillWithData的else正文中使用,尽管正如您所说,fillMe没有使用,所以它可能应该是一个实例变量?或者也许所有的G根本不需要是一个类。 -
@juanpa.arrivillaga:即使递归调用,初始调用者也不会使用最终返回值。
-
你为什么要迭代
dir开始?为什么不直接vars或__dict__? -
@martineau 是的,不过,我怀疑这是一个错字或错误,因为那样整个事情就毫无意义
标签: python object types attributes instance