在具有分层名称

时间:2018-04-03 14:45:38

标签: python ipython

Python officially recognizes名称空间作为一种“鸣叫的好主意”,我们应该“做更多”。名称空间的一个好处是它们的分层表示,它将代码组织成相关的部分。有没有一种优雅的方法将python类方法组织成相关的部分,就像组织分层命名空间一样 - 特别是为了完成制表符的目的?

我的一些python类不能拆分成更小的类,但是附加了许多方法(很容易超过一百)。我也发现(我的代码的用户告诉我)找到有用方法的最简单方法是使用制表符完成。但是由于有这么多方法,这变得笨拙,因为提供了大量选项 - 通常按字母顺序排列,这意味着密切相关的方法可能位于这个庞大列表的完全不同的部分。

通常,存在非常不同的密切相关方法组。例如,我有一个类,其中几乎所有方法都属于四个组之一:

  • IO
  • 统计
  • 转化
  • 对称性

并且io组可能具有读取和写入子组,其中存在用于读取或写入的文件类型的不同选项,然后在查看元数据时涉及一些其他方法。在很小程度上,我可以在我的方法名称中使用下划线来解决这个问题。例如,我可能有像

这样的方法
myobject.io_read_from_csv
myobject.io_write_to_csv

这有助于分类,但是很难看,仍会导致难以处理的制表符完成列表。如果第一个选项卡完成列表只有上面列出的四个选项,那么我更喜欢它,然后当选择其中一个选项时,下一个选项卡将显示其他选项。

对于一个稍微更具体的例子,这里是我为我的班级考虑的层次结构的部分列表:

myobject.io
    myobject.io.read
        myobject.io.read.csv
        myobject.io.read.h5
        myobject.io.read.npy
    myobject.io.write
        myobject.io.write.csv
        myobject.io.write.h5
        myobject.io.write.npy
    myobject.io.parameters
        myobject.io.parameters.from_csv_header
        myobject.io.parameters.from_h5_attributes
        ...
    ...
myobject.statistics
    myobject.statistics.max
    myobject.statistics.max_time
    myobject.statistics.norm
    ...
myobject.transformations
    myobject.transformations.rotation
    myobject.transformations.boost
    myobject.transformations.spatial_translation
    myobject.transformations.time_translation
    myobject.transformations.supertranslation
    ...
myobject.symmetries
    myobject.symmetries.parity
        myobject.symmetries.parity.conjugate
        myobject.symmetries.parity.symmetric_part
        myobject.symmetries.parity.antisymmetric_part
        myobject.symmetries.parity.violation
        myobject.symmetries.parity.violation_normalized
    myobject.symmetries.xreflection
        myobject.symmetries.xreflection.conjugate
        myobject.symmetries.xreflection.symmetric_part
        ...
    ...
...

我可以想象解决此问题的一种方法是在我的主IO类中创建类StatisticsMyClass等类,其唯一目的是存储对{的引用{1}}并提供它所需的方法。然后,主类将具有myobject方法,这些方法只返回那些低级类的实例,然后选项卡完成应该起作用。这有意义吗?例如,在ipython中提供制表符完成是否可行?这会导致循环引用问题吗?还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

看起来我在类中定义类的天真建议确实适用于ipython的tab-completion并且没有任何循环问题。

这是概念验证代码:

class A(object):
    class _B(object):
        def __init__(self, a):
            self._owner = a
        def calculate(self, y):
            return y * self._owner.x

    def __init__(self, x):
        self.x = x
        self._b = _B(self)

    @property
    def b(self):
        return self._b

(事实上,如果我使用self.b = _B(self)会更简单,我可以跳过property,但我喜欢这样,因为它阻止从类外部覆盖b。此外,这表明这种更复杂的情况仍然有效。)

因此,如果我创建a = A(1.2),我可以点击a.<TAB>并获得b作为完成,然后a.b.<TAB>建议calculate作为完成。到目前为止,我的简短测试中没有遇到任何有关此结构的问题,并且对代码的更改不是很大 - 只需将._owner添加到很多方法代码中。