By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,267 Members | 1,800 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,267 IT Pros & Developers. It's quick & easy.

finding name of instances created

P: n/a
Short version of what I am looking for:

Given a class "public_class" which is instantiated a few times e.g.

a = public_class()
b = public_class()
c = public_class()

I would like to find out the name of the instances so that I could
create a list of them e.g.
['a', 'b', 'c']

I've read the Python Cookbook, Python in a Nutshell, Programming
Python, Learning Python, ... googled (probably missed something
obvious), all to no avail.

=====
Longer version:

If I can do the above, I believe I could do the following thing which
is what I am really after eventually.

Given the statement
a = public_class()
I would like to generate
my_dict['a'] = private_class()
so that one could write
a.apparently_simple_method()
and that, behind the scene, I could translate that as
my_dict['a'].not_so_simple_method()
as well as do things like
for name in my_dict:
do_stuff(name)


Any help, pointers, sketches or outline of solution would be greatly
appreciated.

André

Jul 18 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
On Fri, 2005-01-21 at 16:13 -0800, André wrote:
Short version of what I am looking for:

Given a class "public_class" which is instantiated a few times e.g.

a = public_class()
b = public_class()
c = public_class()

I would like to find out the name of the instances so that I could
create a list of them e.g.
['a', 'b', 'c']

I've read the Python Cookbook, Python in a Nutshell, Programming
Python, Learning Python, ... googled (probably missed something
obvious), all to no avail.
Yep. The short answer is that the instances don't have names - they're
just bound to names in a particular scope. They can be bound to
different names in the same scope or in other scopes.

You can get a dictionary for a particular scope using locals() then
search it to find the key for a given value. That key will be the name
the object is bound to in that scope.

In general, you won't want to do that - the need to do so probably
suggests a design issue in what you're trying to do.
If I can do the above, I believe I could do the following thing which
is what I am really after eventually.

Given the statement
a = public_class()
I would like to generate
my_dict['a'] = private_class()
so that one could write
a.apparently_simple_method()
and that, behind the scene, I could translate that as
my_dict['a'].not_so_simple_method()

I'm not clear as to why you can't do this as part of the class of which
'a' is an instance.
as well as do things like
for name in my_dict:
do_stuff(name)


Any help, pointers, sketches or outline of solution would be greatly
appreciated.


I'm not really able to grasp what you're trying to do (but others
might). It wouldn't hurt if you could post a description of what you're
actually trying to achieve - /why/ you want this - as that can often be
very helpful both in understanding what you're thinking and in
suggesting a suitable approach or alternative.

--
Craig Ringer

Jul 18 '05 #2

P: n/a
André wrote:
Given the statement
a = public_class()
I would like to generate
my_dict['a'] = private_class()
so that one could write
a.apparently_simple_method()
and that, behind the scene, I could translate that as
my_dict['a'].not_so_simple_method()
as well as do things like
for name in my_dict:
do_stuff(name)


Why can't you just make public_class a factory, alias the method in
PrivateClass and access the names through locals()?

py> class PrivateClass(object):
.... def not_so_simple_method(self):
.... print "not so simple"
.... apparently_simple_method = not_so_simple_method
....
py> def public_class():
.... return PrivateClass()
....
py> a = public_class()
py> a.apparently_simple_method()
not so simple
py> # add 'name' and 'value' to locals() before iteration starts
py> name, value = None, None
py> for name, value in locals().iteritems():
.... if isinstance(value, PrivateClass):
.... print name, value
....
a <__main__.PrivateClass object at 0x01146D50>

Steve
Jul 18 '05 #3

P: n/a
Craig Ringer wrote:
On Fri, 2005-01-21 at 16:13 -0800, André wrote:
Short version of what I am looking for:

Given a class "public_class" which is instantiated a few times e.g.

a = public_class()
b = public_class()
c = public_class()

I would like to find out the name of the instances so that I could
create a list of them e.g.
['a', 'b', 'c']
[snip]

I'm not really able to grasp what you're trying to do (but others
might). It wouldn't hurt if you could post a description of what you're
actually trying to achieve - /why/ you want this - as that can often be
very helpful both in understanding what you're thinking and in
suggesting a suitable approach or alternative.


Ok, here it goes... I am designing a "learning environment" for Python.
(See rur-ple.sourceforge.org for details of a *very early, still buggy*
relase). I have a "world" in which a
"robot" can accomplish four built-in instructions: move(), turn_left(),
pick_beeper(), put_beeper().
turn_left() corresponds to a 90 degree left turn. One can define a
function to simulate a 90 degree right turn as follows:

def turn_right():
turn_left()
turn_left()
turn_left()

and call it as a built-in instruction thereafter.

By giving more and more complicated tasks for the robot to accomplish,
one can learn various programming concepts using python syntax:
def (as above), while, if, else, elif, ......

I have all of that working well so far (not on sourceforge yet).
Next, I want to introduce
the concept of classes and objects, again using python's syntax.

Behind the scene, I have something like:
robot_dict = { 'robot' = CreateRobot( ..., name = 'robot') }
and have mapped move() to correspond to
robot_dict['robot'].move()
(which does lots of stuff behind the scene.)

I have tested robot_dict[] with more than one robot (each with
its own unique name) and am now at the point where I would like
to have the ability to interpret something like:

alex = CreateRobot()
anna = CreateRobot()

alex.move()
anna.move()

etc. Since I want the user to learn Python's syntax, I don't
want to require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()

I have tried various things at the interpreter, found that
to a class 'a', I could see the instance 'b' created in
locals():
'a': <class '__main__.a'>, 'b': <__main__.a object at 0x011515D0>
which tells me that there must be a way to catch b's name as it is
created, and do what I want to do.

Does this clarify what I am trying to do and why?

André

Jul 18 '05 #4

P: n/a
Using the method suggested by Steven Bethard, I *almost* got it working
the way I would like.
Here's my program:
===
..class PrivateClass(object):
.. dict = {}
.. def not_so_simple_method(self):
.. for name in PrivateClass.dict.keys():
.. if PrivateClass.dict[name] == self:
.. print "instance " + name + " called not so simple"
.. apparently_simple_method = not_so_simple_method

.. def __init__(self):
.. print "instance created"
.. for name, value in globals().iteritems():
.. if isinstance(value, PrivateClass):
.. PrivateClass.dict[name] = value

..def public_class():
.. return PrivateClass()

..print "=== start==="
..alpha = public_class()
..print "created alpha"
..print PrivateClass.dict
..print "### alpha is not there\n"

..beta = public_class()
..print "created beta"
..print PrivateClass.dict
..print "### we are always one behind in the dict content\n"

..alpha.apparently_simple_method()
..beta.apparently_simple_method()
=================================
The output follows:
=== start===
instance created
created alpha
{}
### alpha is not there

instance created
created beta
{'alpha': <__main__.PrivateClass object at 0x0117CDD0>}
### we are always one behind in the dict content

instance alpha called not so simple
=======
Note that instance beta was never recognized when it called "apparently
simple method".

I'm sure there must be a way to do this....

André

Jul 18 '05 #5

P: n/a
André wrote:
Using the method suggested by Steven Bethard, I *almost* got it working
the way I would like.
Here's my program:
===
.class PrivateClass(object):
. dict = {}
. def not_so_simple_method(self):
. for name in PrivateClass.dict.keys():
. if PrivateClass.dict[name] == self:
. print "instance " + name + " called not so simple"
. apparently_simple_method = not_so_simple_method

. def __init__(self):
. print "instance created"
. for name, value in globals().iteritems():
. if isinstance(value, PrivateClass):
. PrivateClass.dict[name] = value

.def public_class():
. return PrivateClass()

.print "=== start==="
.alpha = public_class()
.print "created alpha"
.print PrivateClass.dict
.print "### alpha is not there\n"

.beta = public_class()
.print "created beta"
.print PrivateClass.dict
.print "### we are always one behind in the dict content\n"

.alpha.apparently_simple_method()
.beta.apparently_simple_method()


It looks like you want PrivateClass.dict updated every time that
globals() is updated. You can just use globals directly instead:

py> class PrivateClass(object):
.... def __init__(self, globals):
.... self.globals = globals
.... def apparently_simple_method(self):
.... for name, value in self.globals.iteritems():
.... if value is self:
.... print "instance %s called not so simple" % name
....
py> def public_class():
.... return PrivateClass(globals())
....
py> alpha = public_class()
py> alpha.apparently_simple_method()
instance alpha called not so simple
py> beta = public_class()
py> beta.apparently_simple_method()
instance beta called not so simple

On the other hand, the iteration in
PrivateClass.apparently_simple_method has a very bad code smell...

Steve
Jul 18 '05 #6

P: n/a

Steven Bethard wrote:
André wrote:
Using the method suggested by Steven Bethard, I *almost* got it working the way I would like.
[snip]
It looks like you want PrivateClass.dict updated every time that
globals() is updated.
yes, that is what I would like to do.
You can just use globals directly instead:

py> class PrivateClass(object):
... def __init__(self, globals):
... self.globals = globals
... def apparently_simple_method(self):
... for name, value in self.globals.iteritems():
... if value is self:
... print "instance %s called not so simple" % name
...
py> def public_class():
... return PrivateClass(globals())
...
py> alpha = public_class()
py> alpha.apparently_simple_method()
instance alpha called not so simple
py> beta = public_class()
py> beta.apparently_simple_method()
instance beta called not so simple
That's exactly what I was looking for; thank you!
On the other hand, the iteration in
PrivateClass.apparently_simple_method has a very bad code smell...

I'm not sure what you mean...
Is it because it makes use of information that is
exterior to the class, which is not passed as a parameter
to the method?
[feel free to ignore this question if you want; you have
already helped me tremendously!!!]

André

Jul 18 '05 #7

P: n/a
André Roberge wrote:
Behind the scene, I have something like:
robot_dict = { 'robot' = CreateRobot( ..., name = 'robot') }
and have mapped move() to correspond to
robot_dict['robot'].move()
(which does lots of stuff behind the scene.)

I have tested robot_dict[] with more than one robot (each with
its own unique name) and am now at the point where I would like
to have the ability to interpret something like:

alex = CreateRobot()
anna = CreateRobot()

alex.move()
anna.move()

etc. Since I want the user to learn Python's syntax, I don't
want to require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()


How do you get the commands from the user? Maybe you can preprocess the
user code?

py> class Robot(object):
.... def __init__(self, name):
.... self.name = name
.... def move(self):
.... print "robot %r moved" % self.name
....
py> user_code = """\
.... alex = Robot()
.... anna = Robot()
.... alex.move()
.... anna.move()"""
py> new_user_code = re.sub(r'(\w+)\s+=\s+Robot\(\)',
.... r'\1 = Robot(name="\1")',
.... user_code)
py> print new_user_code
alex = Robot(name="alex")
anna = Robot(name="anna")
alex.move()
anna.move()
py> exec new_user_code
robot 'alex' moved
robot 'anna' moved

Steve
Jul 18 '05 #8

P: n/a
André wrote:
Steven Bethard wrote:
André wrote:
Using the method suggested by Steven Bethard, I *almost* got it
working
the way I would like.


[snip]
It looks like you want PrivateClass.dict updated every time that
globals() is updated.

yes, that is what I would like to do.

You can just use globals directly instead:

py> class PrivateClass(object):
... def __init__(self, globals):
... self.globals = globals
... def apparently_simple_method(self):
... for name, value in self.globals.iteritems():
... if value is self:
... print "instance %s called not so simple" % name
...
py> def public_class():
... return PrivateClass(globals())
...
py> alpha = public_class()
py> alpha.apparently_simple_method()
instance alpha called not so simple
py> beta = public_class()
py> beta.apparently_simple_method()
instance beta called not so simple


That's exactly what I was looking for; thank you!

On the other hand, the iteration in
PrivateClass.apparently_simple_method has a very bad code smell...


I'm not sure what you mean...
Is it because it makes use of information that is
exterior to the class, which is not passed as a parameter
to the method?
[feel free to ignore this question if you want; you have
already helped me tremendously!!!]


There's a couple things I don't like about it:

(1) Generally, I don't like passing globals() around. It's probably
okay in this scenario though because if you want to have the user code
in a different module, you can do something like:
def public_class():
return PrivateClass(usermodule.__dict__)

(2) The really bad code smell however is having to iterate through all
the values in globals to find the key you're looking for... Especially
when you have to check the type of each item... In a perfect world, you
would already have a PrivateClass->name mapping somewhere and this
should be a simple dict lookup instead of an iterative search... See my
other post about potentially pre-processing your user input to see how
you can convert the iteration to a simple attribute lookup.

Steve
Jul 18 '05 #9

P: n/a

Steven Bethard wrote:
André Roberge wrote:
Behind the scene, I have something like:
robot_dict = { 'robot' = CreateRobot( ..., name = 'robot') }
and have mapped move() to correspond to
robot_dict['robot'].move()
(which does lots of stuff behind the scene.)

I have tested robot_dict[] with more than one robot (each with
its own unique name) and am now at the point where I would like
to have the ability to interpret something like:

alex = CreateRobot()
anna = CreateRobot()

alex.move()
anna.move()

etc. Since I want the user to learn Python's syntax, I don't
want to require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()
How do you get the commands from the user? Maybe you can preprocess

the user code?

py> class Robot(object):
... def __init__(self, name):
... self.name = name
... def move(self):
... print "robot %r moved" % self.name
...
py> user_code = """\
... alex = Robot()
... anna = Robot()
... alex.move()
... anna.move()"""
py> new_user_code = re.sub(r'(\w+)\s+=\s+Robot\(\)',
... r'\1 = Robot(name="\1")',
... user_code)
py> print new_user_code
alex = Robot(name="alex")
anna = Robot(name="anna")
alex.move()
anna.move()
py> exec new_user_code
robot 'alex' moved
robot 'anna' moved

Smack! (sound of hand slapping forehead).
Of course! This is *much* better.
(In all honesty, I have trouble reading regular expression
notation but I can decode it enough to understand that I can
do this - and I already asked a question today on the list
about regular expressions, so I have not excuse for not having
thought of an approach like this.)

I will be already 'processing' the code to make sure that
statements/words like: import, exec, eval, input, raw_input, vars,
chr, .... are not allowed in the user-defined instructions.
This will be just a simple addition.

Once again, thank you! Both for this, and for the other example which
taught me something about the use of locals(), globals(), and functions
that return classes. There are so many corners of Python to explore
:-)
Steve


Jul 18 '05 #10

P: n/a
André Roberge wrote:
Behind the scene, I have something like:
robot_dict = { 'robot' = CreateRobot( ..., name = 'robot') }
and have mapped move() to correspond to
robot_dict['robot'].move()
(which does lots of stuff behind the scene.)

I have tested robot_dict[] with more than one robot (each with
its own unique name) and am now at the point where I would like
to have the ability to interpret something like:

alex = CreateRobot()
anna = CreateRobot()

alex.move()
anna.move()

etc. Since I want the user to learn Python's syntax, I don't
want to require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()


If you have access to the user module's text, something like this might
be a nicer solution:

py> class Robot(object):
.... def __init__(self):
.... self.name = None
.... def move(self):
.... print "robot %r moved" % self.name
....
py> class RobotDict(dict):
.... def __setitem__(self, name, value):
.... if isinstance(value, Robot):
.... value.name = name
.... super(RobotDict, self).__setitem__(name, value)
....
py> user_code = """\
.... alex = Robot()
.... anna = Robot()
.... alex.move()
.... anna.move()"""
py> robot_dict = RobotDict()
py> robot_dict['Robot'] = Robot
py> exec user_code in robot_dict
robot 'alex' moved
robot 'anna' moved

Note that I provide a specialized dict in which to exec the user code --
this allows me to override __setitem__ to add the appropriate attribute
to the Robot as necessary.

Steve
Jul 18 '05 #11

P: n/a
On Fri, 21 Jan 2005 21:01:00 -0400, André Roberge wrote:
etc. Since I want the user to learn Python's syntax, I don't want to
require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()


This is just my opinion, but I've been involved with teaching new
programmers before so I think it is an informed one. I don't think you
teach a language by hiding how the language works, no matter what the
intentions.

You should be *minimizing* the magic. You're going to train your students
that Python objects have names (they don't) and that's going to mess them
up later. Actually, it's going to mess them up almost right away, because
how can they have a list of robots like this:

for robot in robots:
robot.turn_left()

That can't work, right, the command inside the loop can only affect the
robot named "robot", right?

You can't teach Python if what you're actually teaching them is a variant
that you have created that is used nowhere else on Earth, and is
internally inconsistent to boot (see loop above, the *real* Python
variable semantics conflict with the semantics you are teaching).

Considering that not a month goes by where someone doesn't post a question
related to this, and it has been a FAQ entry for as long as I've used
Python, I think you are doing a major disservice to your "users" by
training them that objects magically gets the name when assigned. I
strongly urge you to do absolutely no pre-processing of any kind to the
programs they generate. (By which I mean changes to the code; running
pychecker on it would be OK; and I'd urge you to resist the temptation to
process its output, either. Provide a "translation table" if you need to,
but they need to learn to read the real output, too.)

Programming is hard enough with burdening people with "pleasant
falsehoods". Trust your students to handle the truth (and of course
rationally minimize the truth they have to handle, and by using Python
you're off to a great start there). If they can't handle the truth, with
time, effort, and support, they *sure* as hell can't handle lies!
Jul 18 '05 #12

P: n/a
André Roberge <an***********@gmail.com> wrote:
alex = CreateRobot()
anna = CreateRobot()

alex.move()
anna.move()


Hmmmm -- while I've long since been identified as a 'bot, I can assure
you that my wife Anna isn't!
Alex
Jul 18 '05 #13

P: n/a

Jeremy Bowers wrote:
On Fri, 21 Jan 2005 21:01:00 -0400, André Roberge wrote:
etc. Since I want the user to learn Python's syntax, I don't want to require him/her to write
alex = CreateRobot(name = 'alex')
to then be able to do
alex.move()
This is just my opinion, but I've been involved with teaching new
programmers before so I think it is an informed one. I don't think

you teach a language by hiding how the language works, no matter what the
intentions.

You should be *minimizing* the magic. You're going to train your students that Python objects have names (they don't) and that's going to mess them up later. Actually, it's going to mess them up almost right away, because how can they have a list of robots like this:

for robot in robots:
robot.turn_left()
They will not be able to do that.

That can't work, right, the command inside the loop can only affect the robot named "robot", right?

You can't teach Python if what you're actually teaching them is a variant that you have created that is used nowhere else on Earth, and is
internally inconsistent to boot (see loop above, the *real* Python
variable semantics conflict with the semantics you are teaching).

I think you misunderstood my intentions, possibly because I explain
things too superficially.
Considering that not a month goes by where someone doesn't post a question related to this, and it has been a FAQ entry for as long as I've used
Python, I think you are doing a major disservice to your "users" by
training them that objects magically gets the name when assigned. I
strongly urge you to do absolutely no pre-processing of any kind to the programs they generate. (By which I mean changes to the code; running
pychecker on it would be OK; and I'd urge you to resist the temptation to process its output, either. Provide a "translation table" if you need to, but they need to learn to read the real output, too.)

Programming is hard enough with burdening people with "pleasant
falsehoods". Trust your students to handle the truth (and of course
rationally minimize the truth they have to handle, and by using Python you're off to a great start there). If they can't handle the truth, with time, effort, and support, they *sure* as hell can't handle lies!


The environment in which students (my kids first, others later :-) will
learn is based on Richard Pattis's "Karel the Robot" (adapted for
Python in "Guido van Robot"). They are presented with a robot that can
do four basic actions, as I described in a previous post. It's been
used successfully in many places.

The students learn first the procedural aspect of python. Here's a
quick example of a program that they can write:

..def move_and_turn():
.. move()
.. turn_left()
..
..def draw_square():
.. for i in range(4):
.. move_and_turn()
..
..draw_square()
======
At this point, they don't know anything about objects and methods; but
they will have learned about functions and variables. This is where
'Guido van Robot (GvR)', which has been used succesfully to teach
programming using a syntax somewhat similar to python, but not quite,
stops. (Actually, you can't use variables in GvR).

I want to move beyond that and introduce objects and classes.

So, students will be able to write:
pete = CreateRobot(2, 3)
pete.move()

learning about objects and methods.

As for things like
for robot in robots:
do stuff

that will be for my use only: drawing robots on the screen, updating
the 'world' when robots pick stuff up, etc. My intention is that the
students will use the EXACT python syntax, so that they don't know that
*I* have given a *name* to their robot(s) behind the scene.
I have to cut this short; I hope it clarifies my intentions.

André

Jul 18 '05 #14

P: n/a
André Roberge wrote:
Craig Ringer wrote:
On Fri, 2005-01-21 at 16:13 -0800, André wrote:
Short version of what I am looking for:

Given a class "public_class" which is instantiated a few times e.g.

a = public_class()
b = public_class()
c = public_class()

I would like to find out the name of the instances so that I could
create a list of them e.g.
['a', 'b', 'c']


...
Behind the scene, I have something like:
robot_dict = { 'robot' = CreateRobot( ..., name = 'robot') }
and have mapped move() to correspond to robot_dict['robot'].move()
(which does lots of stuff behind the scene.)
...[good explanation]...
Does this clarify what I am trying to do and why?


Yup. Would something like this help?

parts = globals().copy()
parts.update(locals())
names = [name for name, value in parts.iteritems()
if isinstance(value, Robot)] # actual class name here

Note, however, that

a = b = CreateRobot()

will give two different names to the same robot.

And even:

Karl = CreateRobot()
Freidrich = CreateRobot()
for robot in (Karl, Freidrich):
robot.move()

Will have two names for "Freidrich" -- Freidrich and robot
--Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #15

P: n/a
Nick Coghlan wrote:
It also directly addresses the question of aliasing. Think about how
Steven's modified dictionary would react to this code:

pete = CreateRobot(2, 3)
dad = pete
dad.move()
pete.move()


If you'd like to handle these cases, but you don't want to have to
explain aliasing right off the bat, you could try something like:

py> class Robot(object):
.... def __init__(self):
.... self.names = set()
.... def move(self):
.... if len(self.names) == 1:
.... name, = self.names
.... print "robot with name %r moved" % name
.... else:
.... print "robot with names %r moved" % sorted(self.names)
....
py> class RobotDict(dict):
.... def __setitem__(self, name, value):
.... if isinstance(value, Robot):
.... value.names.add(name)
.... super(RobotDict, self).__setitem__(name, value)
....
py> user_code = """\
.... nick = Robot()
.... pete = Robot()
.... dad = pete
.... nick.move()
.... dad.move()
.... pete.move()"""
py> exec user_code in RobotDict(Robot=Robot)
robot with name 'nick' moved
robot with names ['dad', 'pete'] moved
robot with names ['dad', 'pete'] moved

That is, you can just keep track of all the names of a Robot in the
Robot object. In the simple case, where there's only one name, you can
display it as such. In the more complicated case, where there's some
aliasing, you can display the multiple aliases. This means you don't
have to teach about aliasing right off the bat, but if a student
accidentally discovers it on their own, the machinery's there to explain
it...

Steve
Jul 18 '05 #16

P: n/a
Steven Bethard wrote:
That is, you can just keep track of all the names of a Robot in the
Robot object. In the simple case, where there's only one name, you can
display it as such. In the more complicated case, where there's some
aliasing, you can display the multiple aliases. This means you don't
have to teach about aliasing right off the bat, but if a student
accidentally discovers it on their own, the machinery's there to explain
it...


Incidentally, this discussion made me realise the real reason why using a lambda
to create a named function is evil:

Py> def f(): pass
....
Py> f.func_name
'f'
Py> f = lambda: None
Py> f.func_name
'<lambda>'

I think I've heard that explanation before, but it never really clicked.

Cheers,
Nick.

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #17

P: n/a
Nick Coghlan wrote:
Incidentally, this discussion made me realise the real reason why using a lambda to create a named
function is evil:

Py> def f(): pass
...
Py> f.func_name
'f'
Py> f = lambda: None
Py> f.func_name
'<lambda>'

I think I've heard that explanation before, but it never really clicked.


that's nothing you cannot fix, though:
f = lambda: None
f.func_name = "f" f.func_name

'f'

(only works in 2.4 and later, from what I can tell)

</F>

Jul 18 '05 #18

P: n/a
On Fri, 21 Jan 2005 16:13:19 -0800, André wrote:
Short version of what I am looking for:

Given a class "public_class" which is instantiated a few times e.g.

a = public_class()
b = public_class()
c = public_class()

I would like to find out the name of the instances so that I could
create a list of them e.g.
['a', 'b', 'c']

A working solution:

class A:
pass

a = A()
b = A()
c = A()

[x for x,y in locals().items() if
hasattr(y,"__class__") and y.__class__ == A]

That said, you probably dont want to do it. I doubt that it will work
consistently.

BTW, based on my understanding of the other stuff you said, this is
probably not the best way to do whatever it is you are trying to do.

--SegPhault


Jul 18 '05 #19

P: n/a
On Mon, 24 Jan 2005 13:19:45 +0000, Ryan Paul wrote:

A working solution:

class A:
pass

a = A()
b = A()
c = A()

[x for x,y in locals().items() if
hasattr(y,"__class__") and y.__class__ == A]


Just wanted to clarify, because I know that the intellectually deficient
amongst you will say that isinstance is better than using __class__...

In this case isinstance isnt desirable because it will catch
instances of any objects that inherit A, not just instances of A. Observe:

class A: pass
class B(A): pass

a = A()
b = A()
c = A()
d = B()
[x for x,y in locals().items() if isinstance(y,A)] ['a', 'c', 'b', 'd']
[x for x,y in locals().items() if

.... hasattr(y,"__class__") and y.__class__ == A]
['a', 'c', 'b']

-- SegPhault
Jul 18 '05 #20

P: n/a
Op 2005-01-24, Nick Coghlan schreef <nc******@iinet.net.au>:
Steven Bethard wrote:
That is, you can just keep track of all the names of a Robot in the
Robot object. In the simple case, where there's only one name, you can
display it as such. In the more complicated case, where there's some
aliasing, you can display the multiple aliases. This means you don't
have to teach about aliasing right off the bat, but if a student
accidentally discovers it on their own, the machinery's there to explain
it...
Incidentally, this discussion made me realise the real reason why using a lambda
to create a named function is evil:


It is not a named function, it is just a lamda that is assigned to a
name.
Py> def f(): pass
...
Py> f.func_name
'f'
Py> f = lambda: None
Py> f.func_name
'<lambda>'

I think I've heard that explanation before, but it never really clicked.


I just don't see what is so evil about it.

Why is it so trouble some that a function wouldn't have a name, while
most objects don't have a name. Why is it a problem doing something
like:

f = lambda: None

But isn't it a problem doing something like

v = None.
Why don't we demand something like

Py> assign v: None
Py> v.obj_name
'v'

--
Antoon Pardon
Jul 18 '05 #21

P: n/a

Ryan Paul wrote:
On Mon, 24 Jan 2005 13:19:45 +0000, Ryan Paul wrote:

A working solution:

class A:
pass

a = A()
b = A()
c = A()

[x for x,y in locals().items() if
hasattr(y,"__class__") and y.__class__ == A]

Just wanted to clarify, because I know that the intellectually

deficient amongst you will say that isinstance is better than using __class__...
In this case isinstance isnt desirable because it will catch
instances of any objects that inherit A, not just instances of A. Observe:
class A: pass
class B(A): pass

a = A()
b = A()
c = A()
d = B()
[x for x,y in locals().items() if isinstance(y,A)] ['a', 'c', 'b', 'd']
[x for x,y in locals().items() if
... hasattr(y,"__class__") and y.__class__ == A]
['a', 'c', 'b']


Actually, it this case, isinstance *is* desirable (or rather *would
have been*), exactly for the reason that you point out. After teaching
about objects, one of the next subject would be that of inheritance.
E.G.

class BetterRobot(Robot):
.... # create a robot that can turn right directly...

However, I have been convinced that it would be much truer to Python to
give the robot fake names (robot1, robot2, ...), and then have students
name their own robots through declarations like:

cleese = Robot(name="Cleese")

or
cleese = Robot()
cleese.name = "Cleese"
=====
André
-- SegPhault


Jul 18 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.