2

I need to have static or external list, that will be used by every object of A class. The values of the list need to be initialized only once and should be taken from constructor parameters, e.g:

def initialize(x, y):
    for i in range(0, x):
        static_to_return.append([])
        for j in range(0, y):
            static_to_return[i].append((i * x) + 1 + y)
    return static_to_return


class A:
    static_member = initialize(x, y)

    def __init__(self, x, y):
        self.x = x
        self.y = y

How to make this work? Maybe it is better to move the static_member to another module? Or is it possible to write to static_member in __init__ function?

Kacper
  • 726
  • 1
  • 6
  • 22
  • It's not clear what you're expecting to happen. Should this be a static member (actually: class attribute) or initialised from the constructor parameters, which are provided for every instance? What happens when you create a second instance of `A`? Would a class factory (`A = build_A_with(x, y)`) be a better approach? Where (and when) do `x` and `y` even come from? – jonrsharpe Jun 14 '16 at 21:42
  • There will be a lot of `A` class objects and every one of them will have the same `x` and `y` values. What I need is to initialize this attribute with first instantiation of `A` class, based on the constructor parameters. – Kacper Jun 14 '16 at 21:47
  • 1
    If they all have the same `x` and `y`, why are they `__init__` parameters? Those are used to set things that are different for every instance. Where will the values come from, exactly? Could you give some more context, this seems likely to be an [XY (hah!) problem](http://meta.stackexchange.com/q/66377/248731). – jonrsharpe Jun 14 '16 at 21:49

2 Answers2

6

If you want the static member to be initialized from the first object of the class, you could initialize it to None in class definition, and test its value in instance constructor:

class A:
    static_member = None

    def __init__(self, x, y):
        self.x = x
        self.y = y
        if A.static_member is None:  # still not initialized?
            A.static_member = initialize(x, y)  # ok, here it is
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

It seems like you actually want to provide x and y when the class is created, not when an instance is created. If all instances will share the same values, you do not need to provide them as parameters to __init__.

Depending on how complex your class is you may need to use a metaclass for this, but with such a simple example you can just use type:

x = 1
y = 2
A = type('A', (object,), dict(x=x, y=y, static_member=initialize(x, y)))  # *

This creates the class you want and all of the instances share the state you're expecting:

>>> a = A()
>>> b = A()
>>> a.static_member
[[3, 3]]
>>> b.static_member
[[3, 3]]
>>> a.static_member.append(['foo', 'bar'])
>>> a.static_member
[[3, 3], ['foo', 'bar']]
>>> b.static_member
[[3, 3], ['foo', 'bar']]
>>> A.static_member
[[3, 3], ['foo', 'bar']]

* Note that I needed to add the line static_to_return = [] to initialize to get this to run.

Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437