正如标题所示,我试图创建一堆属性,但是代码变得重复和混乱。我想使用< code>closure参数使代码更紧凑。
根据C API参考,闭包是一个函数指针,它为getter/setter提供附加信息。我还没有找到一个使用中的例子。
这是我目前使用它的方式:
static void closure_1() {};
static void closure_2() {};
...
static PyObject *
FOO_getter(FOO* self, void *closure) {
if (closure == &closure_1) {
return self->bar_1;
} else if (closure == &closure_2) {
return self->bar_2;
}
}
static int
FOO_setter(FOO* self, PyObject *value, void *closure) {
if (closure == &closure_1) {
if (somehow value is invalid) {
PyErr_SetString(PyExc_ValueError, "invalid value for bar_1.");
return -1;
}
} else if (closure == closure_2) {
if (somehow value is invalid) {
PyErr_SetString(PyExc_ValueError, "invalid value for bar_2.");
return -1;
}
}
return 0;
}
static PyGetSetDef FOO_getsetters[] = {
{"bar_1", (getter) FOO_getter, (setter) FOO_setter, "bar_1 attribute", closure_1},
{"bar_2", (getter) FOO_getter, (setter) FOO_setter, "bar_2 attribute", closure_2},
{NULL} /* Sentinel */
};
...
它按照我想要的方式工作,但它看起来更像一个黑客,而不是什么“pythonic式”的东西。有没有更好的处理方式?例如以某种方式调用闭包。
尽管有留档,我还是假设闭包
可以是您想要的任何指针。那么传递一个“对象”怎么样,因为C不支持闭包(除了在运行时字面上生成函数)。
在对象中,我们可以将成员的偏移量存储在FOO
中,并存储一个指向特定属性验证器的指针。
typedef int (*Validator)(FOO *, const struct Attribute *, void *);
typedef struct Attribute {
const char *name;
size_t offset;
Validator validator;
} Attribute;
static PyObject **resolve_offset(FOO *self, const Attribute *attr) {
return (PyObject **)( ( (char *)self ) + attr->offset );
}
static PyObject *FOO_getter(FOO *self, void *_attr) {
const Attribute *attr = (const Attribute *)_attr;
return *resolve_offset(self, attr);
}
static int FOO_setter(FOO *self, PyObject *val, void *_attr) {
const Attribute *attr = (const Attribute *)_attr;
if (attr->validator(self, attr, val)) {
*resolve_offset(self, attr) = val;
return 0;
} else {
// Building the string to include attr->name is left to you.
PyErr_SetString(PyExc_ValueError, "invalid value.");
return -1;
}
}
static int FOO_bar_1_validator(FOO *self, const Attribute *attr, void *val) { ... }
static int FOO_bar_2_validator(FOO *self, const Attribute *attr, void *val) { ... }
#define ATTRIBUTE(name) \
static Attribute FOO_ ## name ## attr = { \
#name, \
offsetof(FOO, name), \
FOO_ ## name ## _validator \
};
ATTRIBUTE(bar_1);
ATTRIBUTE(bar_2);
#define PY_ATTR_DEF(name) { \
#name, \
(getter)FOO_getter, \
(setter)FOO_setter, \
#name " attribute", \
&(FOO_ ## name ## attr) \
}
static PyGetSetDef FOO_getsetters[] = {
PY_ATTR_DEF(bar_1),
PY_ATTR_DEF(bar_2),
{ NULL }
};
我最初写道:
< code>resolve_offset当然依赖于未定义的行为,但它应该工作得很好。另一种选择是在我们的属性对象中有三个函数(get、validate、set ),而不是一个,但是这忽略了问题的关键。
但@tstanisl指出,它看起来不像UB。令人惊叹的
我猜这个闭包是用来向Foo_getter
传递一个额外的上下文。它应该是简化访问Foo
成员的东西。文档可能是错误的。它应该是“可选指针”,而不是“可选函数指针”。
考虑传递成员的偏移量。通过在 stddef.h
中定义的宏的标准偏移,可以很容易地获得到结构杆件的偏移。它是一个小的无符号整数,适合 void*
类型。
static PyGetSetDef FOO_getsetters[] = {
{"bar_1", (getter) FOO_getter, (setter) FOO_setter, "bar_1 attribute", (void*)offsetof(FOO, bar_1)},
{"bar_2", (getter) FOO_getter, (setter) FOO_setter, "bar_2 attribute", (void*)offsetof(FOO, bar_2)},
{NULL} /* Sentinel */
};
现在,获取者可以是:
static PyObject *
FOO_getter(FOO* self, void *closure) {
// pointer to location where the FOO's member is stored
char *memb_ptr = (char*)self + (size_t)closure;
// cast to `PyObject**` because `mem_ptr` points to location where a pointer to `PyObject` is stored
return *(PyObject**)mem_ptr;
}
对setter使用类似的模式。
我正在使用log4j管理Clojure应用程序中的日志记录。我希望能够使用系统变量为log4j中的单个包设置日志级别。属性文件。例如,下面是我的基本属性文件: 这将日志级别设置为中的DEBUG(特定日志代码所在的位置)。然而,我不希望这样——我希望它在本地是调试的,在生产上是信息的。所以,我使用一个环境变量: 这个实例中的设置为,我可以通过使用环境变量将日志级别设置为DEBUG来确认它是否可以正常
问题内容: 我正在使用PropertiesConfiguration加载和存储属性值。 如果我在属性值中使用字符“ /”,则将其另存为“ \ /”。您能帮我只保存“ /”而不是“ \ /”吗?我在这里想念什么吗? 保存后,我的属性文件的值为 谢谢, 问题答案: 进行转义以满足属性文件格式的要求。的JavaDoc中介绍了这种格式。 如果那 不是 您想要的,那么您实际上就不需要属性文件,而是需要其他(
正如我从thymeleaf文档中了解到的那样,我尝试了:
问题内容: hibernate中的property标签的lazy属性允许按照以下链接延迟加载属性:http : //docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/mapping.html#mapping- declaration -属性 lazy(可选-默认为false):指定在首次访问实例变量时应延迟获取此属性。它需要构建时字节码检测
我希望将JavaFX属性用于UI绑定,但我不希望它们出现在我的模型类中(请参见在模型类中使用JavaFX.Beans属性)。我的模型类有getter和setter,我想基于这些创建属性。例如,假设一个实例具有和方法,我将编写 希望会触发对的调用。但这似乎不起作用。我错过了什么?
问题内容: 我为该标题表示歉意。我找不到更好的方法来解释这种情况。 我使用URL http://www.exampledepot.com/egs/java.util/Props.html中所述的Property类加载属性文件。 我的问题是我可以在该属性文件中使用属性吗? 例: test.properties 其他语法有可能吗? 谢谢 问题答案: 以前从未见过。您当然 可以 制作自己的预处理器。只要