python类的行为类似于字典或列表数据

时间:2016-09-02 06:57:19

标签: python list class dictionary

在python3控制台中,输入:

>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=4, micro=3, releaselevel='final', serial=0)
>>> type(sys.version_info)  # this is class type
<class 'sys.version_info'>
>>> sys.version_info[0:2]  # ?? But it acts like a list-data-like
(3, 4)

我的问题是:

  1. 一个类如何像字典或列表数据一样?
  2. 可以举一个例子来构建这样的类吗?
  3. 是否有一些文档 此?

4 个答案:

答案 0 :(得分:2)

这很容易......您需要做的就是定义一个处理切片或整数/字符串查找的__getitem__方法。你可以做任何你想做的事情......

class Foo(object):
    def __init__(self, bar, baz):
        self.bar = bar
        self.baz = baz
    def __getitem__(self, ix):
        return (self.bar, self.baz).__getitem__(ix)

以下是在以下情况下将__getitem__传递给ix的作弊表:

f[1]  # f.__getitem__(1)
f[1:]  # f.__getitem__(slice(1, None, None))
f[1:, 2]  # f.__getitem__( (slice(1, None, None), 2) )
f[1, 2]  # f.__getitem__( (1, 2) )
f[(1, 2)]  # f.__getitem__( (1, 2) )

技巧(可能稍微不重要)就是简单地编写__getitem__,以便它查看传递的对象的类型,然后做正确的事情。对于我的回答,我在tuple中创建了一个__getitem__,然后在元组上调用了__getitem__,因为它在我想要的所有情况下都做了正确的事情支持)

以下是一些示例用法:

>>> f = Foo(1, 2)
>>> f[1]
2
>>> f[0]
1
>>> f[:]
(1, 2)

请注意,您通常不会 自己需要这样做。您可以创建named tuple来为您完成工作:

from collections import namedtuple
Foo = namedtuple('Foo', 'bar, baz')

用法几乎相同:

>>> f = Foo(1, 2)
>>> f[1]
2
>>> f[0]
1
>>> f[:]
(1, 2)

这里的主要区别是我们的namedtuple是不可变的。一旦创建,我们就无法改变它的成员。

答案 1 :(得分:2)

Python包含emulating container types的几种方法,例如字典和列表。

特别要考虑以下课程:

 class MyDict(object):
     def __getitem__(self, key):
          # Called for getting obj[key]

     def __setitem__(self, key, value):
          # Called for setting obj[key] = value

如果你写

obj = MyDict()

然后

obj[3]

将调用第一个方法,并

obj[3] = 'foo'

将调用第二种方法。

如果您想进一步支持

len(obj)

然后你只需要添加方法

def __len__(self):
    # Return here the logical length

这是一个由列表

实现的(非常低效)字典的示例
class MyDict(object):
    def __init__(self, seq=None):
        self._vals = list(seq) if seq is not None else []

    def __getitem__(self, key):
        return [v[1] for v in self._vals if v[0] == key][0]

    def __setitem__(self, key, val):
        self._vals = [v for v in self._vals if v[0] != key]
        self._vals.append((key, val))

    def __len__(self):
        return len(self._vals)

您可以像常规dict一样使用它:

obj = MyDict()
obj[2] = 'b'
>>> obj[2]
'b'

答案 2 :(得分:0)

我认为在python中像ECMAScript(又名javascript)类是字典或关联数组associative array)。因为您可以在运行时向类中添加属性或方法。(see

class A(object):
    def __init__(self):
        self.x = 0
a = A()
a.y=5
print a.y # 5

如果您想编写类似的类,可以使用__getitem____setitem__方法:

class A(object):
    class B(object):
        def __init__(self, x, y):
            self.vals = (x, y)
        def __getitem__(self, key):
            return self.vals[key]
        def __setitem__(self, key, val):
            self.vals[key] = val
        def __len__(self):
            return len(self.__vals)
    def __init__(self, x, y):
        self.b = self.B(x,y)



a = A('foo','baz')

print type(a.b) # __main__.b     __main__ because we run script straightly
print a.b[:]    # ('foo', 'baz')

答案 3 :(得分:0)

您可以通过在班级中覆盖 getitem ()和 setitem ()来实现相同的行为。

df1

您也可以在类中覆盖 setitem ()来实现setter类型的东西。