我有一个类CameraInterface
,有两个属性:
recording
(布尔值)recording_quality
(具有三个可能值的枚举)用户可以按硬件按钮(这是一个Raspberry Pi项目)来选择recording_quality
,但是如果相机已经recording
,则硬件将闪烁/buzz/否则表明您在录制时无法更改recording_quality
。你知道吗
我希望CameraInterface
对象强制执行这个要求。我不希望未来的我能够忘记这个要求,并且不小心尝试设置recording_quality
而不首先确保recording is False
。做这件事最像Python的方法是什么?你知道吗
我最熟悉Objective-C,在这里我可以尝试在外部readonly
创建属性,然后执行以下操作:
- (void)setQuality:(Quality)quality
successHandler:(void (^)(void))successHandler
failureHandler:(void (^)(void))failureHandler
{
if ( self.recording ) {
if ( failureHandler ) {
failureHandler();
}
}
else {
self.quality = quality; // internally writable
if ( successHandler ) {
successHandler();
}
}
}
更新
关于我要找的东西的澄清:
recording_quality
的有时可设置的特性构建到CameraInterface
的编程接口中,这样您就不必等到运行时才发现自己做错了什么。你知道吗更新2
我被Martijn Pieters’s answer说服使用运行时异常,并在尝试设置recording_quality
时使用try/catch。让我信服的部分原因是我试图用Python实现我的Objective-C示例。这样做,我意识到它确实更适合静态类型的语言。让我信服的部分原因是Martijn答案中链接的答案,它更详细地解释了异常是Python控制流的一个非常正常的部分。你知道吗
这是上面Objective-C示例的Python版本。我把它放在这里作为对其他人的警告:
import types
class CameraInterface(object):
def __init__(self):
self._recording_quality = 1
self.recording = False
@property
def recording_quality(self):
return self._recording_quality
def set_recording_quality(self, quality, success_handler, failure_handler):
if type(success_handler) is not types.FunctionType:
raise ValueError("You must pass a valid success handler")
if type(failure_handler) is not types.FunctionType:
raise ValueError("You must pass a valid failure handler")
if self.recording is True:
# reject the setting, and call the failure handler
failure_handler()
else:
self._recording_quality = quality
success_handler()
def success():
print "successfully set"
def failure():
print "it was recording, so we couldn't set the quality"
camera = CameraInterface()
print "recording quality starting at {0}".format(camera.recording_quality)
camera.set_recording_quality(3, success, failure)
camera.recording = True
camera.set_recording_quality(2, success, failure)
这张照片:
recording quality starting at 1
successfully set
it was recording, so we couldn't set the quality
您可以使用properties:
可以使用其setter引发异常的^{} :
其中} 的子类。你知道吗
CurrentlyRecordingError
是一个自定义异常;它可以是^{在Python中,使用exceptions是处理在特定情况下无法设置的属性的最自然的方法。另见Is it a good practice to use try-except-else in Python?
另一种方法是使用Look-before-you-leap方法,每次要设置质量值时,都必须显式地测试相机录制状态。这会使API复杂化,并且很容易导致竞速条件,即在测试状态之后但在更改质量设置之前,摄像机开始录制。你知道吗
对于一个异常,您可以使用Ask for Forgiveness;这简化了对象的使用,因为您假设可以进行质量设置,并且可以在异常处理程序中处理只读情况。你知道吗
从Python的角度(除了不使用属性之外)对Objective-C版本的进一步说明:
type(..) is [not] typeobj
。你知道吗types.FunctionType
不同,您可以使用^{if
语句已经在测试真值;使用is True
不仅是多余的,而且在与其他比较运算符一起使用时会导致难以调试的错误,因为这些运算符是链接的。value == someothervalue is True
并不是你所认为的意思。你知道吗您需要为属性创建同名的Python方法,然后为getter和setter功能使用
@property
decorator:这允许您执行以下操作:
相关问题 更多 >
编程相关推荐