【发布时间】:2012-10-10 16:37:18
【问题描述】:
我今天在 jython 中使用 java 对象时遇到了问题,因为 jython 试图变得智能并自动为(简单)getter/setter 方法创建属性 - 对于每个方法,删除前导 get/set 的字段并创建下一个转换为小写的字母:
//java code
class MyClass {
public List<Thing> getAllThings() { ... }
public List<Thing> getSpecificThings(String filter) { ... }
public void setSomeThing(SomeThing x) { ... }
[...]
}
#jython code
obj = MyClass()
hasattr(obj, "allThings") #-> True
hasattr(obj, "specificThings") #-> False because getSpecificThings has a param
hasattr(obj, "someThing") #-> False BUT
"someThing" in dir(obj) #-> True
最后一行在这里总结了我的问题 - dir 的结果包含这些字段(即使在 obj.class 而不是 obj 上执行时)。我需要一个可在对象上调用的所有方法的列表,对于我的对象来说,这基本上是 dir 没有这些属性的结果,并被过滤以排除从 java.lang.Object 继承的所有内容以及以下划线开头的内容(这样做的目的是自动将一些 python 类转换为 java 等价物,例如 dicts 到 Maps)。理论上我可以使用不包含它们的__dict__,但这意味着我也必须递归地评估基类的__dict__s,我想避免这种情况。我目前正在做的是查看该属性是否确实存在,然后检查它是否具有argslist 属性(意味着它是一种方法),除了生成的属性之外的每个dir 条目都是如此:
for entry in dir(obj):
#skip things starting with an underscore or inherited from Object
if entry.startswith("_") or entry in dir(java.lang.Object): continue
#check if the dir entry is a fake setter property
if not hasattr(obj, entry): continue
#check if the dir entry has an argslist attribute (false for getter props)
e = getattr(obj, entry)
if not hasattr(e, "argslist"): continue
#start actual processing of the entry...
这种方法的问题在于,所讨论的对象是 bean 的接口,而 getSomething 方法通常从数据库中获取数据,因此对属性的 getattr 调用会往返于数据库,这可能需要几秒钟的时间,并且浪费大量内存。
我可以阻止 jython 生成这些属性吗?如果没有,是否有人知道我如何过滤出属性而不先访问它们?我唯一能想到的就是检查dir 是否包含一个名为get/set<property> 的方法,但这似乎很不自然,可能会产生误报,必须避免。
【问题讨论】:
标签: jython