的Python:是否有可能使一个类可迭代使用标准的语法? [英] Python: Is it possible to make a class iterable using the standard syntax?

查看:242
本文介绍了的Python:是否有可能使一个类可迭代使用标准的语法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承与只不过类的对象很多大型类成分(整数,字符串等)的项目。我想能够检查一个属性是present而不需要手动定义的属性列表。

有可能的的迭代器本身使用标准语法,以一个Python?也就是说,我希望能够遍历所有使用在富ATTR类的属性:(甚至如果ATTR在富),而不需要先创建类的实例。我想我可以通过定义 __ __ ITER ,但到目前为止,我还没有完全管理有什么我要找的做到这一点。

我已经通过添加取得了一些我想要的东西__ __ ITER 方法,像这样:

 类Foo:
    巴=栏
    巴兹= 1
    @staticmethod
    高清__iter __():
        返回ITER([ATTR因为如果在DIR(美孚attr)使用ATTR [:2] =__])

不过,这并没有完全完成我在寻找:


 >>>在富X:
...打印(X)
回溯(最近通话最后一个):
  文件<&标准输入GT;,1号线,上述<&模块GT;
类型错误:'classobj'对象不是可迭代


但即便如此,这个作品:


 >>>在富.__ ITER __ X():
...打印(X)
酒吧
巴兹



解决方案

__ ITER __ 添加到元类,而不是类本身(假设的Python 2.x的):

 类Foo(对象):
    巴=栏
    巴兹= 1
    类__metaclass __(类型):
        高清__iter __(个体经营):
            在DIR(美孚)ATTR:
                如果没有attr.startswith(__):
                    产量ATTR

对于Python 3.x中,用

 类MetaFoo(类型):
    高清__iter __(个体经营):
        在DIR(美孚)ATTR:
            如果没有attr.startswith(__):
                产量ATTRFoo类(元类= MetaFoo):
    巴=栏
    巴兹= 1

I have inherited a project with many large classes constituent of nothing but class objects (integers, strings, etc). I'd like to be able to check if an attribute is present without needed to define a list of attributes manually.

Is it possible to make a python class iterable itself using the standard syntax? That is, I'd like to be able to iterate over all of a class's attributes using for attr in Foo: (or even if attr in Foo) without needing to create an instance of the class first. I think I can do this by defining __iter__, but so far I haven't quite managed what I'm looking for.

I've achieved some of what I want by adding an __iter__ method like so:

class Foo:
    bar = "bar"
    baz = 1
    @staticmethod
    def __iter__():
        return iter([attr for attr in dir(Foo) if attr[:2] != "__"])

However, this does not quite accomplish what I'm looking for:

>>> for x in Foo:
...     print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'classobj' object is not iterable

Even so, this works:

>>> for x in Foo.__iter__():
...     print(x)
bar
baz

解决方案

Add the __iter__ to the metaclass instead of the class itself (assuming Python 2.x):

class Foo(object):
    bar = "bar"
    baz = 1
    class __metaclass__(type):
        def __iter__(self):
            for attr in dir(Foo):
                if not attr.startswith("__"):
                    yield attr

For Python 3.x, use

class MetaFoo(type):
    def __iter__(self):
        for attr in dir(Foo):
            if not attr.startswith("__"):
                yield attr

class Foo(metaclass=MetaFoo):
    bar = "bar"
    baz = 1

这篇关于的Python:是否有可能使一个类可迭代使用标准的语法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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