static? + some stuff

D

Daniel Schüle

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)
 
E

Eric Brunel

Daniel said:
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

You just did:
> class foo:
> a = b = None
> c = 0
> my_id = 0

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.
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?

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).
thanks for your time

HTH
 
J

John Roth

Daniel Schüle said:
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

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.
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?

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
 
K

KefX

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):
1)
is there a way do declare static variables in a class?

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?
2)
is there a way to see the types of all data/function members of a class?

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

- Kef
 
D

Daniel Schüle

[...]
a, b, c and my_id *are* class attributes. They are actually inherited by

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)
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
(...)

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?
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.

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


[...]
for i in attr:
print type(getattr(tmp, i))

exactly this :)

Thank you and all others for the answears
 
A

Alex Martelli

Daniel said:
[...]
a, b, c and my_id *are* class attributes. They are actually inherited by

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)

Yes, for example the built-in function for accessing, checking etc
are named getattr, hasattr, setattr, delattr

from you code above i dont see the declarations of c, my_id ...

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
 
D

Daniel Schüle

[...]
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

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!!!

[...]
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top