我今天在 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 等价物,例如地图的字典)。理论上我可以使用__dict__
which 不包含它们,但这意味着我也必须递归地评估基类__dict__
,我想避免这种情况。我目前正在做的是查看属性是否确实存在,然后检查它是否有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>
,但这看起来很骇人,并且可能会产生误报,必须避免这种情况。