覆盖__dir__方法的正确方法是什么? [英] What is the correct way to override the __dir__ method?

查看:134
本文介绍了覆盖__dir__方法的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题更多地是关于 __ dir __ 而不是 numpy

This question is meant to be more about __dir__ than about numpy.

我有一个的子类numpy.recarray (在python 2.7中,numpy 1.6.2),我注意到了 recarray dir 对象时未列出字段名称(因此ipython的自动完成功能不起作用)。

I have a subclass of numpy.recarray (in python 2.7, numpy 1.6.2), and I noticed recarray's field names are not listed when diring the object (and therefore ipython's autocomplete doesn't work).

尝试修复它,我尝试在我的子类中覆盖 __ dir __ ,如下所示:

Trying to fix it, I tried overriding __dir__ in my subclass, like this:

def __dir__(self):
    return sorted(set(
               super(MyRecArray, self).__dir__() + \
               self.__dict__.keys() + self.dtype.fields.keys()))

结果为: AttributeError:'super'对象没有属性'__dir __'
(我发现这里这应该在python 3.3中实际工作......)

which resulted with: AttributeError: 'super' object has no attribute '__dir__'. (I found here this should actually work in python 3.3...)

作为解决方法,我试过:

As a workaround, I tried:

def __dir__(self):
    return sorted(set(
                dir(type(self)) + \
                self.__dict__.keys() + self.dtype.fields.keys()))

据我所知,这个有效,但当然不是很优雅。

As far as I can tell, this one works, but of course, not as elegantly.

问题:


  1. 后一种解决方案在我的情况下是正确的,即对于 recarray ?

  2. 有没有办法让它在一般情况下有效?在我看来它不适用于多重继承(打破超级 - 调用链),当然,对于没有 __ dict __ <的对象/ code> ...

  3. 您知道为什么 recarray 不支持列出其字段名称开头吗?仅仅是疏忽?

  1. Is the latter solution correct in my case, i.e. for a subclass of recarray?
  2. Is there a way to make it work in the general case? It seems to me it wouldn't work with multiple inheritance (breaking the super-call chain), and of course, for objects with no __dict__...
  3. Do you know why recarray does not support listing its field names to begin with? mere oversight?


推荐答案

Python 2.7 +,3.3 + class mixin,简化了方法。希望它会有所帮助。 要点

Python 2.7+, 3.3+ class mixin that simplifies implementation of __dir__ method in subclasses. Hope it will help. Gist.

import six
class DirMixIn:
    """ Mix-in to make implementing __dir__ method in subclasses simpler
    """

    def __dir__(self):
        if six.PY3:
            return super(DirMixIn, self).__dir__()
        else:
            # code is based on
            # http://www.quora.com/How-dir-is-implemented-Is-there-any-PEP-related-to-that
            def get_attrs(obj):
                import types
                if not hasattr(obj, '__dict__'):
                    return []  # slots only
                if not isinstance(obj.__dict__, (dict, types.DictProxyType)):
                    raise TypeError("%s.__dict__ is not a dictionary"
                                    "" % obj.__name__)
                return obj.__dict__.keys()

            def dir2(obj):
                attrs = set()
                if not hasattr(obj, '__bases__'):
                    # obj is an instance
                    if not hasattr(obj, '__class__'):
                        # slots
                        return sorted(get_attrs(obj))
                    klass = obj.__class__
                    attrs.update(get_attrs(klass))
                else:
                    # obj is a class
                    klass = obj

                for cls in klass.__bases__:
                    attrs.update(get_attrs(cls))
                    attrs.update(dir2(cls))
                attrs.update(get_attrs(obj))
                return list(attrs)

            return dir2(self)

这篇关于覆盖__dir__方法的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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