我创建了一个类,其属性都是可选的。目前,我的代码完全被try: ... except AttributeError: ...
块所折磨,但我想知道这是否是最好的方法。
我现在正在改变我对每个未知属性使用None
类型的方法,这使得我的代码在我看来看起来更好,但我仍然想知道是否有更好的方法或者我是否需要处理随着可选性的测试。
我正在尝试制作一个Coordinates
,它必须以特殊的方式进行修改,并且通常不会提前知道,但必须在其他一些实例的帮助下进行计算,这就是为什么值必须是可选的。
很高兴听到您的经历和建议。
编辑:
谢谢大家的回答!你们都很快......虽然我很慢,很抱歉。
由于这个主题非常抽象,我不得不花更多的时间来思考它。
我接受你的回答,Ethan作为解决方案,因为我认为这是我将调查的下一个方向。我将发布一些代码来澄清以下陈述。 __add__
例程的旧代码看起来像这样:
def __add__(self, other):
"""Add the given *masses* and calculate the resulting center of
gravity. *other* must be a :meth:`putzmeister.Masse` instance or 0.
"""
if other == 0:
result = self.copy()
result.label = None
return result
elif not isinstance(other, type(self)):
raise TypeError('Error: second operand is not a Masse instance')
mass = self.masse + other.masse
result = type(self)(masse=mass)
try: result.x = (self.x*self.masse + other.x*other.masse)/mass
except AttributeError: pass
try: result.y = (self.y*self.masse + other.y*other.masse)/mass
except AttributeError: pass
try: result.z = (self.z*self.masse + other.z*other.masse)/mass
except AttributeError: pass
result._set_categories( self, other, action='add')
return result
现在看起来像这样:
def __add__(self, other):
"""Overwrite operator "+": add the given masses and calculate the resulting center of
gravity.
"""
if other == 0:
result = self.copy()
result.label = None
return result
elif not isinstance(other, type(self)):
raise TypeError('Error: second operand is not a Masse instance')
mass = self.masse + other.masse
result = type(self)(masse=mass)
for a in ('x','y','z'):
c1 = getattr(self, a)
c2 = getattr(other,a)
if c1 is None or c2 is None: setattr(result, a, None)
else: setattr(result, a, (c1*self.masse + c2*other.masse)/mass )
result._set_categories( self, other, action='add')
return result
None类型可以正常为<unset state>
。现在的问题是0是所有坐标的有效值,所以我总是要检查if attribute is not None
而不是if attribute
,这是我认为最好的代码可以得到的。
然而,我的梦想是在作业z = x + y
中我的代码能够首先检查z是否存在并且具有正确的类型,然后如果是,则设置可以导出的x和y的值通过数学语句(例如对于y:如果z具有某些属性且x具有相同的属性...)如果z不存在则创建它并且设置所有可设置的值。不太确定这样的事情是否可以完成......
再次感谢大家的回答。
答案 0 :(得分:1)
他们真的不需要在那里,或者他们是否应该有默认值?无论哪种方式,似乎你已经学会了更好的方法 - 如果同一个类的所有实例都具有相同的属性,那就更好了。
使用None
是处理未初始化名称的标准方法,但如果None
可以作为有效值,则可以创建自己的名称:
class UnInit(object):
"""
No value yet given to this attribute
"""
class Coordinate(object):
x = UnInit
y = UnInit
z = UnInit