如何允许自定义类参数在 ipython 中制表符完成?

Posted

技术标签:

【中文标题】如何允许自定义类参数在 ipython 中制表符完成?【英文标题】:How to allow custom Class parameter to be tab-completed in ipython? 【发布时间】:2014-04-27 17:16:45 【问题描述】:

例如,如果我有以下课程

class Part(object):
    def __init__(self,part_number,description,rev=None,color=None):
        self.dims = 
        self.dim_id = 0
        self.rev = rev
        if type(color) is tuple:
            self.color=(color[0]/255.,color[1]/255.,color[2]/255.)
        else:
            self.color = color

     def add_dimension(self,description,value,tol,tol_type = 'sym',dwg_sheet = None, dwg_zone = None,quality = 3):
        self.dims[description] = Dimension(description=description,part=self,value=value,tol=tol,tol_type=tol_type,quality=quality,dwg_sheet=None,dwg_zone=None)


    def __getattr__(self, description):
        return self.dims[description]

class Dimension(object):
    def __init__(self,part,value,tol,tol_type = 'sym', dwg_sheet = None, dwg_zone = None, quality = 3, description = None):
        self.value = value
        self.part=part
        self.tol = tol
        self.tol_type = tol_type
        self.description = description
        self.quality = quality
        self.sigma = self.tol/float(quality)


    def __str__(self):
    return self.description

然后我运行以下代码:

a = Part('pn','this is a part')
a.add_dimension('this_is_a_dimension',1.00,0.05)
print a.this_is_a_dimension

返回:

this_is_a_dimension

问题是当我在输入“a.”后尝试完成制表符时,我只得到以下选项

a.add_dimension
a.color
a.dim_id
a.dims
a.rev

我希望能够通过制表符完成来查看我的新参数。它类似于 Pandas Dataframes 中列名的工作方式。

有什么想法吗?

【问题讨论】:

另见this question 【参考方案1】:

你可以。你必须为你的类实现一个__dir__() 方法,正如here 所讨论的那样。

这是它工作的一个例子:

class bar(object):
    def __init__(self,):
        self.a = 4
        self._morelements=['b']
    def __dir__(self):
        return sorted(set(dir(type(self)) + list(self.__dict__) + self._morelements))

foo=bar()

现在,如果您在 Ipython 中编写 foo. 并按 TAB,您将拥有 ab 作为可用成员,尽管 b 不存在。

__dir__() 的代码以及对这种方法的局限性的讨论是here。在您的情况下,您希望将description 添加到函数add_dimension() 内的列表self._morelements

编辑: 当然你还需要在__init__()中初始化self._morelements=[],并将上例的__dir__()函数添加到你的类Part

【讨论】:

【参考方案2】:

Python 被解释。所以,它只知道它已经解释过的代码。这方面的一个例子是:如果您尝试运行您发布的代码,您将在以下行收到错误:

self.dims[description] = Dimension(description=description,part=self,value=value,tol=tol,tol_type=tol_type,quality=quality,dwg_sheet=None,dwg_zone=None)

错误:未定义全局名称“Dimension”。那是因为你在之后定义了 Dimension 类。在解释器到达该行时,Dimension 类不存在。

athis_is_a_dimension 属性只存在于运行时和行后:

a.add_dimension('this_is_a_dimension',1.00,0.05)

为了完成你想要的,你需要一些在编辑时解释 python 代码的 IDE。

【讨论】:

我相信iPython必须这样做,否则我不确定pandas是如何实现这种效果的。 @Chris 我同意。 iPython 必须在内部运行您正在编写的 python 代码。这就是它可以自动完成大多数对象属性的原因。 那么我该如何设置它以显示动态属性?

以上是关于如何允许自定义类参数在 ipython 中制表符完成?的主要内容,如果未能解决你的问题,请参考以下文章

我如何自定义制表符到空间的转换因子?

使用 TailwindCSS 和 Typography 插件,我如何允许在 .prose 中使用类进行自定义?

如何以自定义漂亮的日志格式在每个新行上附加制表符?

xposed自定义参数

如何在 JNI 中使用自定义类类型参数调用 Java 函数

Emacs - 本地 Python 变量的制表符补全