static? + some stuff

Discussion in 'Python' started by Daniel Schüle, Nov 3, 2003.

  1. Hi all

    I have 2 questions
    1)
    is there a way do declare static variables in a class?
    I coded this logic in global variable foo_cnt
    2)
    is there a way to see the types of all data/function members of a class?
    dir(cls) returns a list of strings (of members) so it's logical that
    type(tmp.i) fails ...
    is it possible at all?

    thanks for your time

    --
    Daniel


    foo_cnt = 0 #<<<<<replace for static

    class foo:
    a = b = None
    c = 0
    my_id = 0
    def __init__(self, c = 0):
    global foo_cnt
    foo_cnt+=1
    self.my_id = foo_cnt
    self.c = c
    def show(self):
    print self.a, self.b, self.c
    def move(self):
    print "ID = ", self.my_id, "\tc = ", self.c

    print dir(foo) #shows all member of 'foo'

    x = foo(12)
    y = foo(123)

    print foo_cnt
    x.show()
    y.show()

    def print_type_of_all_attr_of_class(cls):
    tmp = cls()
    attr = dir(cls) #or dir(tmp)
    print attr
    for i in attr:None
    #print type(tmp.i)

    print_type_of_all_attr_of_class(foo)
     
    Daniel Schüle, Nov 3, 2003
    #1
    1. Advertisements

  2. Daniel Schüle

    Eric Brunel Guest

    You just did:
    a, b, c and my_id *are* class attributes. They are actually inherited by
    instances of foo, but declaring them this way makes them class attributes. You
    should have done:

    class foo:
    cnt = 0
    def __init__(self, c=0):
    foo.cnt += 1
    self.a = self.b = None
    self.c = c
    self.my_id = foo.cnt
    (...)

    Attributes do not need to be *declared* at the top of the class in Python as in
    C++ or Java: initializing them in the __init__ method is enough, and is probably
    the safest way to handle them.
    Use the getattr built-in function:

    def print_type_of_all_attr_of_class(cls):
    tmp = cls()
    attr = dir(tmp)
    print attr
    for i in attr:
    print type(getattr(tmp, i))

    print_type_of_all_attr_of_class(foo)

    You can see here that cnt is actually declared as an attribute of the *class*
    foo, since you see it when you do a dir(cls), but not when you do a dir(tmp).
    HTH
     
    Eric Brunel, Nov 3, 2003
    #2
    1. Advertisements

  3. Daniel Schüle

    John Roth Guest

    Yes, but it isn't as easy as a declaration. There are
    basically two ways to do it. One (which works on
    any version of Python) is to reference the class object
    directly when setting the variable. For example:

    class Foo:
    staticVar = None
    def setStaticVar(self, value):
    Foo.staticVar = value

    The other is possible in release 2.2 and later:

    class Foo:
    staticVar = None
    def setStaticVar(klas, value):
    klas.staticVar = value
    setStaticVar = classmethod(setStaticVar)

    In the first example, setStaticVar is a normal
    method that gets the instance as the first
    parameter. In the second one, setStaticVar
    gets the class object as the first parameter,
    which is why I've named it klas instead of self.
    No. In general, instance variables are not represented in the
    class object, so they won't show up if you only look at it.
    If you want to look at the class object and a running instance
    object, then you should be able to get all of the variables
    and methods. Of course, if inheritance is involved, then you
    would have to run the inheritance graph as well to find them.
    You'd still have to write a bit of code (using getattr) to get
    the actual objects and then make sense out of it, though.

    John Roth
     
    John Roth, Nov 3, 2003
    #3
  4. Daniel Schüle

    KefX Guest

    Some other people have replied already, but I don't think they've sufficiently
    explained a possible gotcha (it's easy to spot for the experienced, but it can
    catch newbies off-guard, and nobody likes chasing bugs for a couple hours):
    In the sense of C++ and Java? Yup, sure is.
    .... bar = 5 # Notice this is NOT set in __init__

    This binds 'bar' to the class 'foo', and not any of its instances.
    6

    This suggests the value of foo.bar is shared throughout class instances: and it
    is. But it's not bound to the class instances. In other words, if you print out
    the __dict__ of baz, you won't find 'bar' in it anywhere (you'll get an empty
    dictionary). It's in the __dict__ of foo, though, along with a couple other
    things.

    THIS MEANS YOU CANNOT CHANGE baz.bar, ONLY foo.bar.
    6

    What happened? Well, assigning to baz.bar "overrided" the class variable: it
    assumes that we want to bind a NEW variable named 'bar' to the class INSTANCE
    rather than to the CLASS, and our 'static' behavior is smashed for this
    particular instance. This is good if you want it, bad if you don't.

    In other words, if you want a 'static' variable, for the expression "baz.bar is
    foo.bar" to be True, baz must not have an item named bar in its dictionary.

    Get it?
    Do you mean the class, the class instance, or both? I hope my previous example
    has shown there's a very important difference.

    - Kef
     
    KefX, Nov 3, 2003
    #4
  5. [...]
    just to adjust myself to the Python's terminology
    is the word "member" not widely used in Python?
    is it better to say "attributes"?
    (for both member functions and member variables)
    i think i've got it
    the only thing bothering me is that you cant see(less readability) from
    ...
    cnt = 0
    ...
    is "cnt" considered to be used as "static" or not
    what if i would write ...
    foo.cnt += 1 #static
    and later in one of member functions
    self.cnt = 1 #non static

    or issues such usage an error ..

    and one more question :)
    from you code above i dont see the declarations of c, my_id ...
    is it sufficient just to write self.c=0 instead of doing it the way i did in
    my original
    posting (where i put them additional at the top for the readability)?
    but do the both ways express logical the same thing?
    as I figured out from tests, one has to initalize every variable with
    something
    at least with None (and that's fine so)
    is there a need to differentiate between assignment and initialization?
    (like in C++)
    btw in C++ you can also declare member variables at the bottom
    indeed that's my favorite style there, but since i am new to Python
    i found it more readable (dont ask me why) to place them at the top

    i am sure there are must be some "coding styles" in use around ..
    pointers in this direction are very approciated


    [...]
    exactly this :)

    Thank you and all others for the answears
     
    Daniel Schüle, Nov 4, 2003
    #5
  6. Yes, for example the built-in function for accessing, checking etc
    are named getattr, hasattr, setattr, delattr

    No declarations: a name springs into existence when you first assign to it
    (or otherwise bind it, e.g. with a 'def name():...' statement).

    It's most readable if you assign all of an instance's attributes
    in the __init__ method -- it's not mandatory, but it's what is most
    normally done and expected, whence the readability "from habit".


    Alex
     
    Alex Martelli, Nov 4, 2003
    #6
  7. [...]
    after long thinking i came to the conclusion that .. from what KefX said ..
    "assigning to it .. would smash 'static' for this instance of the class"
    i would say ...

    class some_class:
    cnt = 0
    def __init__(self):
    foo.cnt += 1
    self.my_id = foo.cnt
    def some_func(self):
    self.cnt = 100
    def print(self):
    print foo.cnt

    x = some_class()
    x.print() #1
    y = some_class()
    y.print() #2

    x.some_func() #<--- smashes cnt ONLY for x instance?!?!
    x.print() #100

    z = some_class() #..but not for the instances that might come
    z.print() #3

    i haven't tested that, ALL OUTPUT assumed!!!

    [...]
     
    Daniel Schüle, Nov 4, 2003
    #7
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.