以下是Python中descriptor用法的一个简单示例:
class MyDescriptor(object):
def __get__(self, obj, objtype):
return 42
class MyClass(object):
d = MyDescriptor()
print MyClass().d # 42
但是,如果我希望描述符对象成为类的实际属性,那么MyClass().d
将是MyDescriptor
实例,而不是42。
答案 0 :(得分:1)
有很多方法可以获得你想要的东西,具体取决于你想要的东西。
如果您只想访问描述符对象(即,您不关心它是否实际上直接存储为类的属性),那么只需将其存储在列表或其他内容中:
class Foo(object):
descriptor = [MyDescriptor()]
这需要额外的间接级别来访问它,但在实践中,这可能比替代方案更少。
如the documentation中所述,描述符通过object.__getattribute__
激活。因此,如果您真的希望它是一个属性,您可以在包含描述符(__getattribute__
)的类上覆盖MyClass
,从而阻止描述符机制生效:
class MyClass(object):
d = MyDescriptor()
def __getattribute__(self, attr):
if attr=='d':
return self.__class__.__dict__['d']
else:
return super(MyClass, self).__getattribute__(attr)
>>> MyClass().d
<__main__.MyDescriptor object at 0x0000000002843E80>
答案 1 :(得分:1)
getattr_static()无法解析描述符,例如slot 在C中实现的对象上的描述符或getset描述符 返回描述符对象的基础属性。
>>> import inspect
>>> inspect.getattr_static(MyClass, 'd')
<__main__.MyDescriptor object at 0x105678c18>
>>> inspect.getattr_static(MyClass(),"d")
<__main__.MyDescriptor object at 0x105678c18>
如果您希望将此设置为实例的默认行为,则可以将__getattribute__
覆盖为getattr_static
:
class MyClass(object):
from inspect import getattr_static as __getattribute__
d = MyDescriptor()
>>> MyClass().d
<__main__.MyDescriptor object at 0x105678c18>
坦率地说,我不明白为什么你会想要这个,将描述符存储在一个不会调用像dict
这样的描述符的数据结构中会更有意义:
descriptors = {"d": MyDescriptor()}
然后你可以查找descriptors["d"]
而不会有调用描述符的风险。
答案 2 :(得分:0)
我最简单的想法是将这个描述符包装成另一个描述符。它可以工作,因为只会调用一个try {
String path = "upload/1.jpg";
Path p = Paths.get(path);
InputStream is = new FileInputStream(p.toFile());
res.raw().setContentType(Files.probeContentType(p));
res.raw().setHeader("Content-Disposition", "inline; filename=" + p.getFileName());
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) > 0) {
res.raw().getOutputStream().write(buffer, 0, len);
}
String result = IOUtils.toString(is);
is.close();
return result.trim();
} catch (Exception e) { // handle the exceptions the way you want
logger.error("Error while getting resource", e);
res.status(500);
return "";
}
。
__get__