我有一个情况,我有几个项目,我想用with块打开.在我的情况下,这些是外部硬件设备,在关闭时需要进行一些清理 - 但这对于手头的要点并不重要.
假设一个类是这样的:
class Controller(object):
def __init__(self, name):
self._name = name
def __enter__(self):
# Do some work on entry
print("Entering", self._name)
return self
def __exit__(self, type, value, traceback):
# Clean up (restoring external state, turning off hardware, etc)
print("Exiting", self._name)
return False
def work(self):
print("Working on", self._name)
Run Code Online (Sandbox Code Playgroud)
我会(给定一定数量的Controllers),做类似的事情
with Controller("thing1") as c1:
with Controller("thing2") as c2:
c1.do_work()
c2.do_work()
Run Code Online (Sandbox Code Playgroud)
但是,我遇到过这样一种情况:我需要以这种方式管理一些灵活的事情.也就是说,我的情况类似于:
things = ["thing1", "thing2", "thing3"] # flexible in size
for thing in things:
with Controller(thing) as …Run Code Online (Sandbox Code Playgroud) 我经常编写代码,这些代码最终都是长序列
int error;
error = do_something();
if (error) {
return error;
}
error = do_something_else(with, some, args);
if (error) {
return error;
}
error = do_something_yet_again();
if (error) {
return error;
}
return 0;
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种更清晰的方式来写这个,这在某种程度上避免了重复的相同检查.到目前为止,我已经编写了一个ERROR_OR宏,它的工作方式类似于
#define ERROR_OR(origerr, newerr) \
({ \
int __error_or_origerr = (origerr); \
(__error_or_origerr != 0) \
? __error_or_origerr \
: (newerr); \
})
Run Code Online (Sandbox Code Playgroud)
这允许原始代码变得像
int error = 0;
error = ERROR_OR(error, do_something());
error = ERROR_OR(error, do_something_else(with, some, args));
error = ERROR_OR(error, do_something_yet_again());
return error; …Run Code Online (Sandbox Code Playgroud) 如果我有一个类型
enum foo {
FOO,
BAR,
BAZ,
};
Run Code Online (Sandbox Code Playgroud)
然后我可以声明该类型的原子版本吗
_Atomic(enum foo);
Run Code Online (Sandbox Code Playgroud)
或者我必须使用egatomic_int并投射结果atomic_load()?
以下程序编译时不会出现警告:
#include <stdatomic.h>
#include <stdio.h>
enum foo {FOO, BAR, BAZ};
int main(void) {
_Atomic(enum foo) foo_a;
atomic_store(&foo_a, BAR);
enum foo val = atomic_load(&foo_a);
printf("%u\n", val);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但也是如此:
#include <stdatomic.h>
#include <stdio.h>
enum foo {FOO, BAR, BAZ};
int main(void) {
enum foo foo; // <---- non atomic
atomic_store(&foo, BAR);
enum foo val = atomic_load(&foo);
printf("%u\n", val);
return 0;
}
Run Code Online (Sandbox Code Playgroud)