如何pythonically有部分相互排斥的可选参数? [英] How to pythonically have partially-mutually exclusive optional arguments?

查看:123
本文介绍了如何pythonically有部分相互排斥的可选参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个简单的例子,拿 椭圆可以返回其属性如面积 A ,周长 C ,主要/次要轴线 A / b ,偏心率电子等。为了得到一明显具有提供precisely它的两个参数,以获得所有其他的人,虽则作为一个特殊的情况下只提供一个参数应该承担一个圆。三个或三个以上参数的一致性应该产生一个警告,但工作,否则显着提高一个例外。

As a simple example, take a class Ellipse that can return its properties such as area A, circumference C, major/minor axis a/b, eccentricity eetc. In order to get that, one obviously has to provide precisely two of its parameters to obtain all the other ones, though as a special case providing only one parameter should assume a circle. Three or more parameters that are consistent should yield a warning but work, otherwise obviously raise an exception.

所以,有效的椭圆取值一些例子是:

So some examples of valid Ellipses are:

Ellipse(a=5, b=2)
Ellipse(A=3)
Ellipse(a=3, e=.1)
Ellipse(a=3, b=3, A=9*math.pi)  # note the consistency

而无效问卷,将

Ellipse()
Ellipse(a=3, b=3, A=7)

构造将因此无论是包含许多 =无参数,

class Ellipse(object):
    def __init__(self, a=None, b=None, A=None, C=None, ...):

或者,可能是比较明智​​的,一个简单的 ** kwargs ,也许添加选项提供 A,B 作为位置参数,

or, probably more sensible, a simple **kwargs, maybe adding the option to provide a,b as positional arguments,

class Ellipse(object):
    def __init__(self, a=None, b=None, **kwargs):
        kwargs.update({key: value
                       for key, value in (('a', a), ('b', b))
                       if value is not None})

到目前为止,一切都很好。但现在来的实际执行,即搞清楚提供了哪些参数,哪些没有,并确定取决于他们所有的人,或者如果需要检查一致性。

So far, so good. But now comes the actual implementation, i.e. figuring out which parameters were provided and which were not and determine all the others depending on them, or check for consistency if required.

我的第一个方法是很多的一个简单而乏味的组合

My first approach would be a simple yet tedious combination of many

if 'a' in kwargs:
    a = kwargs['a']
    if 'b' in kwargs:
        b = kwargs['b']
        A = kwargs['A'] = math.pi * a * b
        f = kwargs['f'] = math.sqrt(a**2 - b**2)
        ...
    elif 'f' in kwargs:
        f = kwargs['f']
        b = kwargs['b'] = math.sqrt(a**2 + f**2)
        A = kwargs['A'] = math.pi * a * b
        ...
    elif ...

* 。但有没有更好的办法?或者,这是一流的设计完全胡说八道,我应该创建构造,如 Ellipse.create_from_a_b(A,B),尽管基本上打出了提供三个或三个以上的参数一致选项不可能?

and so on*. But is there no better way? Or is this class design totally bollocks and I should create constructors such as Ellipse.create_from_a_b(a, b), despite that basically making the "provide three or more consistent parameters" option impossible?

奖金的问题:既然椭圆的周长涉及到椭圆积分(或如果椭圆函数周提供,并且要获得的其他参数),这是不准确的计算琐碎,应当这些计算实际上是在构造或而被放入 @属性Ellipse.C

Bonus question: Since the ellipse's circumference involves elliptic integrals (or elliptic functions if the circumference is provided and the other parameters are to be obtained) which are not exactly computationally trivial, should those calculations actually be in the constructor or rather be put into the @property Ellipse.C?

* 我想至少有一个可读性改善将永远提取 A B 和计算从他们的休息,但是这意味着重新计算已经提供的值,浪费了时间和precision ...

* I guess at least one readability improvement would be always extracting a and b and calculating the rest from them but that means recalculating the values already provided, wasting both time and precision...

推荐答案

我的建议主要集中在的数据封装以及code可读性。

My proposal is focused on data encapsulation and code readability.

A)选择上unambigous测量对在内部重新present椭圆

a) Pick pair on unambigous measurements to represent ellipse internally

class Ellipse(object):
    def __init__(a, b):
        self.a = a
        self.b = b

二)创建属性的家庭获得所需的有关椭圆指标

b) Create family of properties to get desired metrics about ellipse

class Ellipse(object):
    @property
    def area(self):
        return math.pi * self._x * self._b

c)建立工厂类/ factory方法与unambigous名称:

c) Create factory class / factory methods with unambigous names:

class Ellipse(object):
    @classmethod
    def fromAreaAndCircumference(cls, area, circumference):
        # convert area and circumference to common format
        return cls(a, b)

使用范例:

ellipse = Ellipse.fromLongAxisAndEccentricity(axis, eccentricity)
assert ellipse.a == axis
assert ellipse.eccentricity == eccentricity

这篇关于如何pythonically有部分相互排斥的可选参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆