473,320 Members | 1,979 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Discover instance variables

Ok, I know there has to be a way to do this, but my google-fu fails me
(once more). I have a class with instance variables (or should they be
called attributes, I'm newish to programming and get really confused
with OO sometimes), like the one in this example:

class Foo():
self.a = "bar"
self.z = "test"
self.var = 2

foo = Foo()

I want to print a list of the variables (strings, integers, etc) in
Foo, without knowing their names. So that the user who needs to change
a peice of information can view the variable list, enter the name of
the variable they need to change and then make the change. This is
what I'd like a sample run to look like:

Attributes for foo:
a = bar
z = test
var = 2

Change: a
New value: foobar
Change made!

I can handle the formatting and changing the variable itself, no
problem, but how do I get a list of all the variables in a class
instance? I almost put a list in there called vars and appended all
the variables to it so I could iterate the list, but this sounds like
something useful enough that someone has come up with a better way to
do it than that. It almost looks like self.__dir__() is what I want,
but that returns methods as well, correct? I only want variables, but
I can't think of how to do a list comprehension that would remove the
methods.

JonathanB

Jul 16 '07 #1
7 1487
JonathanB wrote:
Ok, I know there has to be a way to do this, but my google-fu
fails me (once more). I have a class with instance variables (or
should they be called attributes, I'm newish to programming and
get really confused with OO sometimes),
To complete confusion, those terms vary with languages :)
like the one in this example:

class Foo():
self.a = "bar"
self.z = "test"
self.var = 2
This will not work. Please use working code for examples.
I can handle the formatting and changing the variable itself, no
problem, but how do I get a list of all the variables in a class
instance? I almost put a list in there called vars and appended
all the variables to it so I could iterate the list, but this
sounds like something useful enough that someone has come up with
a better way to do it than that.
I'd use exactly this, since there may be attributes you don't want
to be changed from outside (perhaps __class__).
It almost looks like self.__dir__() is what I want, but that
returns methods as well, correct? I only want variables, but I
can't think of how to do a list comprehension that would remove
the methods.
That's quite a problem with your concept. There are no variables and
methods. There are only attributes. Attributes may be objects. Some
objects may be callable (like function objects).

If you know exactly what you want to be accessible like this, you
could filter __dir__() output with name/callable/isinstance tests.

Regards,
Björn
--
BOFH excuse #320:

You've been infected by the Telescoping Hubble virus.

Jul 16 '07 #2
En Mon, 16 Jul 2007 14:25:48 -0300, JonathanB <do******@gmail.com>
escribió:
Ok, I know there has to be a way to do this, but my google-fu fails me
(once more). I have a class with instance variables (or should they be
called attributes, I'm newish to programming and get really confused
with OO sometimes), like the one in this example:

class Foo():
self.a = "bar"
self.z = "test"
self.var = 2

foo = Foo()

I want to print a list of the variables (strings, integers, etc) in
Foo, without knowing their names. So that the user who needs to change
a peice of information can view the variable list, enter the name of
the variable they need to change and then make the change. This is
You should define more precisely *which* attributes do you actually want
in the list, but I think this may serve as a starting point:

pydef get_attributes(obj):
.... return [attr for attr in dir(obj) if not attr.startswith('_') and
.... type(getattr(obj,attr)) in (
.... int,str,unicode,float,dict,list,tuple)]
....
pyf=open("c:\\test.py")
pyget_attributes(f)
['mode', 'name', 'softspace']

The list keeps only the types explicitely enumerated. Other types are
excluded, as well as names starting with "_". Another criterion would be
`not attr.startswith('_') and not callable(getattr(obj,attr))`

--
Gabriel Genellina

Jul 16 '07 #3
JonathanB wrote:
Ok, I know there has to be a way to do this, but my google-fu fails me
(once more). I have a class with instance variables (or should they be
called attributes, I'm newish to programming and get really confused
with OO sometimes), like the one in this example:
Instance variable are indeed attributes, but you are doing fine with the
language so don't worry about it.
class Foo():
self.a = "bar"
self.z = "test"
self.var = 2
That's unlikely to work, though: the code is in the context of the
class, not one of its methods, so unless you happen to be declaring a
class inside another class's method it's unlikely that there's going to
be a "self" around when those three lines execute.

What you probably want is something like what follows (I am running it
interactively so I know I am telling the truth: it keeps me honest :-).
You should get used to using the interpreter to check your hypotheses -
it would have told you you were making a mistake above as soon as you
tried to create a Foo.
>>class Foo:
.... a = "bar"
.... z = "test"
.... var = 2
....

You can check that Foo (the class) has these attributes:
>>Foo.a
'bar'
foo = Foo()
Now foo is an instance of the Foo class. Class attributes can also be
accessed through instances:
>>foo = Foo()
foo.var
2
>>>
Binding an instance attribute, however, doesn't change the class, so you
can use class attributes as a kind of "default" for instance.
>>foo.a = "foo"
foo.a
'foo'
>>Foo.a
'bar'
>>>
I want to print a list of the variables (strings, integers, etc) in
Foo, without knowing their names. So that the user who needs to change
a peice of information can view the variable list, enter the name of
the variable they need to change and then make the change. This is
what I'd like a sample run to look like:

Attributes for foo:
a = bar
z = test
var = 2

Change: a
New value: foobar
Change made!

I can handle the formatting and changing the variable itself, no
problem, but how do I get a list of all the variables in a class
instance? I almost put a list in there called vars and appended all
the variables to it so I could iterate the list, but this sounds like
something useful enough that someone has come up with a better way to
do it than that. It almost looks like self.__dir__() is what I want,
but that returns methods as well, correct? I only want variables, but
I can't think of how to do a list comprehension that would remove the
methods.
[name for name in dir(x) if not callable(name) and not
name.startswith("__")]

might come close - I presume you don't want __doc__ and the like.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

Jul 16 '07 #4
class Foo():
self.a = "bar"
self.z = "test"
self.var = 2

That's unlikely to work, though: the code is in the context of the
class, not one of its methods, so unless you happen to be declaring a
class inside another class's method it's unlikely that there's going to
be a "self" around when those three lines execute.
Ah, I see. Trouble is I write most of my code on a computer that
doesn't have python (shared computer and I don't have permissions to
install). So I code it here, email it to myself, and test it at home.
I had my debugged code at home so I couldn't post a working example.
Here's working example.

class World():
def __init__(self, name, WTN, Ag, Na, Ex, In, Ni, Al, Port, Type,
Dia, Grav, Atmosphere, Hyd, Climate, Pop, Gov, CR, TL, Wealth,
Trade=None, notes=None):
self.name = name
self.WTN = WTN
self.Ag = Ag
self.Na = Na
self.Ex = Ex
self.In = In
self.Ni = Ni
self.Al = Al
self.Port = Port
self.Trade = Trade
self.Type = Type
self.Dia = Dia
self.Grav = Grav
self.Atmosphere = Atmosphere
self.Hyd = Hyd
self.Climate = Climate
self.Pop = Pop
self.Gov = Gov
self.CR = CR
self.TL = TL
self.Wealth = Wealth
self.notes = notes

The code to execute this is:

def world_info():
# code to prompt for each variable
world = World(name, WTN, Ag, Na, Ex, In, Ni, Al, Port, Type, Dia,
Grav, Atmosphere, Hyd, Climate, Pop, Gov, CR, TL, Wealth)

So given that example, is there a clean way to get this output:

Data for Earth:
Name = Earth
WTN = 5.0
Ag = 0
Na = 0
....
....
Notes = None
[name for name in dir(x) if not callable(name) and not
name.startswith("__")]
That does looks almost exactly like what I want I think (I'm still
learning to read code to learn what it does, but from what it looks
like this does a list comprehension that removes everything callable
and that starts with "__")
[name for name in dir(x) if not callable(name) and not
name.startswith("__")]

might come close - I presume you don't want __doc__ and the like.
Jul 16 '07 #5
Gabriel Genellina <ga*******@yahoo.com.arwrote:
The list keeps only the types explicitely enumerated. Other types are
excluded, as well as names starting with "_". Another criterion would be
`not attr.startswith('_') and not callable(getattr(obj,attr))`
Why not:

In [1]: class Foo(object):
...: a = 3
...:
...:

In [2]: import inspect

In [4]: inspect.getmembers(Foo())
Out[4]:
[('__class__', <class '__main__.Foo'>),
('__delattr__', <method-wrapper '__delattr__' of Foo object at
0x12bf350>),
('__dict__', {}),
('__doc__', None),
('__getattribute__',
<method-wrapper '__getattribute__' of Foo object at 0x12bf350>),
('__hash__', <method-wrapper '__hash__' of Foo object at 0x12bf350>),
('__init__', <method-wrapper '__init__' of Foo object at 0x12bf350>),
('__module__', '__main__'),
('__new__', <built-in method __new__ of type object at 0x307860>),
('__reduce__', <built-in method __reduce__ of Foo object at
0x12bf350>),
('__reduce_ex__', <built-in method __reduce_ex__ of Foo object at
0x12bf350>),
('__repr__', <method-wrapper '__repr__' of Foo object at 0x12bf350>),
('__setattr__', <method-wrapper '__setattr__' of Foo object at
0x12bf350>),
('__str__', <method-wrapper '__str__' of Foo object at 0x12bf350>),
('__weakref__', None),
('a', 3)]

and then filter out __xyz__ methods?
--
Lawrence, oluyede.org - neropercaso.it
"It is difficult to get a man to understand
something when his salary depends on not
understanding it" - Upton Sinclair
Jul 16 '07 #6
In article <11**********************@n60g2000hse.googlegroups .com>,
JonathanB <do******@gmail.comwrote:
I can handle the formatting and changing the variable itself, no
problem, but how do I get a list of all the variables in a class
instance? I almost put a list in there called vars and appended all
the variables to it so I could iterate the list, but this sounds like
something useful enough that someone has come up with a better way to
do it than that. It almost looks like self.__dir__() is what I want,
but that returns methods as well, correct? I only want variables, but
I can't think of how to do a list comprehension that would remove the
methods.
For simple cases, the object's __dict__ will probably give you what you
want. By default, that's where an object's instance variables are
stored, and you can just examine the keys, etc:

class Foo(object):
def __init__(self):
self.a = "bar"
self.z = "test"
self.var = 2

foo = Foo()
print foo.__dict__

-{'a': 'bar', 'var': 2, 'z': 'test'}

However, there are lots of ways to bypass using the __dict__ to hold
attributes. If the class uses any of these techniques, __dict__ either
will not exist or may not be complete. A few of the techniques that
come to mind are:

* custom __getattr__/__setattr__ methods (or __getattribute__ in a new
style class)

* descriptors (http://docs.python.org/ref/descriptors.html)

* using __slots__ in a new style class
Dave
Jul 18 '07 #7
JonathanB wrote:
So given that example, is there a clean way to get this output:

Data for Earth:
Name = Earth
WTN = 5.0
Ag = 0
Na = 0
...
...
Notes = None
Sure, save the __init__ parameters explicitly in a dict.

self.data = {"Name": name,
"WTN": WTN,
"Ag": Ag,
...
}

To display them, you can iterate through the dict:

print "Data for Earth:"
for field, content in self.data.items():
print "%s = %r" % field, content

Hope that helps.

Regards,
Björn

--
BOFH excuse #188:

...disk or the processor is on fire.

Jul 18 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: David MacQuigg | last post by:
I am writing a chapter for teaching OOP in Python. This chapter is intended as a brief introduction to replace the more complete discussion in Learning Python, 2nd ed, pp. 295-390. I need to...
6
by: Martin | last post by:
I'd like to be able to get the name of an object instance from within a call to a method of that same object. Is this at all possible? The example below works by passing in the name of the object...
2
by: Byrocat | last post by:
Wondering if anyone has made use of this feature? The manuals don't seem to be very clear on it but it appears that if you have a connection already created to one instance on that particular...
2
by: Earl Teigrob | last post by:
I am programming ASP.NET using C#. I have been accessing static variables accross my entire application but now need to change some of the static variables that are session specific to instance...
20
by: Shawnk | last post by:
I would like to get the class INSTANCE name (not type name) of an 'object'. I can get the object (l_obj_ref.GetType()) and then get the (l_obj_typ.Name) for the class name. I there any way of...
12
by: titan nyquist | last post by:
I have a class with data and methods that use it. Everything is contained perfectly THE PROBLEM: A separate thread has to call a method in the current instantiation of this class. There is...
2
by: hvj | last post by:
Does IIS create a separate instance of a webservice for each call to it or if more calls are done at the same time, is it possible that the same instance will be used for more calls? So do I...
2
by: Nikolaus Rath | last post by:
Hello, I am really surprised that I am asking this question on the mailing list, but I really couldn't find it on python.org/doc. Why is there no proper way to protect an instance variable...
45
by: =?Utf-8?B?QmV0aA==?= | last post by:
Hello. I'm trying to find another way to share an instance of an object with other classes. I started by passing the instance to the other class's constructor, like this: Friend Class...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.