简体   繁体   中英

How to create objects with array-properties in Python

I am looking for a way to implement an object as an array with different attributes in Python. My idea is an object-index looking like this:

self[row][col].item1 = True
self[row][col2].item2="xkcd"
...

I'm pretty sure I saw this before, however I can't recreate a class which allows this. My best call so far is (in dummy-code):

def __init__(self, posxy=[[...]*10]):
    self.posxy=posxy

which at least allows me to give the attribute posxy all informations I want. However I would strongly prefer the first variant. Could someone with more experience in object-oriented programming please help me out?

You want to look at the Emulating container types section of the Python datamodel.

At the very least, you'll have to implement the __getitem__ hook to let your class handle [...] indexing. This will only be pass the first row value, whatever this method returns will be indexed for [col] .

You can choose to handle tuples instead, indexing on self[row, col] too, the key argument will then be passed a tuple of two values instead:

def __getitem__(self, key):
    row, col = key  # unpack the tuple
    return self.matrix[row][col]

To use the [] notation you need to override the __getitem__ special method. A simple example:

class X:
    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        return self.data[index]

So to have rows and columns you can try the following:

class Row:
    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        return self.data[index]

class Matrix:
    def __init__(self, data):
        self.data = [Row(d) for d in data]

    def __getitem__(self, index):
        return self.data[index]

Simple demo:

class X:
    def __init__(self, value):
        self.item1 = value

x = Matrix([[X('11'), X('12'), X('13')], [X('21'), X('22'), X('23')]])

print x[1][1].item1

Gives:

>>>22

You can inherit from defaultdict to get something like this:

import collections

class MyClass(collections.defaultdict):
  def __init__(self):
    collections.defaultdict.__init__(self, dict)
    self[0][0] = True
    self[0][1] ="xkcd"

ie, each top-level index yields a dict . If you want something more structured, your defaultdict needs a different factory function ... maybe it yields a MyInnerClass which is also a defaultdict, containing your eventual type.

All defaultdict is doing for you is implementing __getitem__ , __setitem__ , __contains__ etc. See Martijn's link for the full list of methods, if you want to implement it by hand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM