假设我想要一个名为Num的类,它包含一个数字,一半和它的正方形。
我应该可以修改三个变量中的任何一个,它将影响它的所有相关成员变量。我应该能够使用三个值中的任何一个来实例化该类。
设计这个课程的最佳方法是什么,以便可以轻松修改并确保我不会遗漏任何东西?
我应该存储所有三个号码还是只存储主号码?
例如,这就是我在python中使用我的类的方法:
num = Num(5)
print num.n, num.half, num.square
它应该打印5,2.5和25
这很简单,但我也想用它的一半初始化。
num = Num(half=2.5)
print num.n, num.half, num.square
它还应该打印5,2.5和25
如何让init函数知道它的一半?
我还想修改任何一个号码,它会改变所有相关号码! E.g:
num.square = 100
print num.n, num.half, num.square
它应该打印10,5和100
任何关于如何设计课程的建议都将受到赞赏。
答案 0 :(得分:4)
您需要属性,设置或获取任何值。使用关键字参数可以实现__init__
的不同行为:
class Num(object):
def __init__(self, n=None, half=None, square=None):
self._n = 0
if n is not None:
self.n = n
if half is not None:
self.half = half
if square is not None:
self.square = square
@property
def n(self):
return self._n
@n.setter
def n(self, n):
self._n = n
@property
def half(self):
return self._n * 0.5
@half.setter
def half(self, n):
self._n = n * 2
@property
def square(self):
return self._n ** 2
@square.setter
def square(self, n):
self._n = n ** 0.5
n = Num(square=100)
print n.half
编辑:现在没有lambdas,在初始化时没有给出值,给出一个很好的默认值,否则不会产生AttributeError
。
答案 1 :(得分:4)
与@Daniel相同的解决方案 - 扩展,lambda-less,Python 3.3:
class Num:
#class Num(object): for Python 2.
def __init__(self, n = None, half = None, square = None):
if n is not None:
self.n = n
elif half is not None:
self.half = half
elif square is not None:
self.square = square
else:
self.n = 0
@property
def n(self):
return self.__n
@n.setter
def n(self, n):
self.__n = n
@property
def half(self):
return self.n / 2.0
@half.setter
def half(self, n):
self.n = n * 2
@property
def square(self):
return self.n ** 2
@square.setter
def square(self, n):
self.n = n ** .5
>>> five = Num(n=5)
>>> five.half, five.n, five.square, five._Num__n
(2.5, 5, 25, 5)
>>>
答案 2 :(得分:1)
对于其他方法,您可以在__setattr__
中应用逻辑:
class Num(object):
def __init__(self, n=None, half=None, square=None):
if all(arg is None for arg in (n, half, square)):
raise ValueError("Must supply at least one arg.")
if n is not None:
self.n = n
elif half is not None:
self.half = half
elif square is not None:
self.square = square
def __setattr__(self, key, value):
dct = self.__dict__
if key == "n":
dct[key] = value
dct["half"] = value / 2.
dct["square"] = value ** 2
elif key == "half":
dct[key] = value
dct["n"] = value * 2
dct["square"] = self.n ** 2
elif key == "square":
dct[key] = value
dct["n"] = value ** .5
dct["half"] = self.n / 2.
else:
dct[key] = value