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

How To capture an id into an array..

P: n/a
Hello everybody!!!

I'm pretty much new to this OOP...

I have a problem..

Here is a part of code that I'm writing

class V(E):
""" This is a variable for MPY"""
def __init__(self):
print id(self)
check=[]
check.append(id(self))
self.val = None

what I do is call say v1=V() so it means that v1 belongs to the
variable class..

Again if I call v2=V() so now v2 also belong to this class.. I want
to keep a track of all the instances of this class.. and store their
ids in an array..

any help in this regards is appreciated...

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


P: n/a
BALAJI RAMAN wrote:
Hello everybody!!!

I'm pretty much new to this OOP...

I have a problem..

Here is a part of code that I'm writing

class V(E):
""" This is a variable for MPY"""
def __init__(self):
print id(self)
check=[]
check.append(id(self))
self.val = None

what I do is call say v1=V() so it means that v1 belongs to the
variable class..

Again if I call v2=V() so now v2 also belong to this class.. I want
to keep a track of all the instances of this class.. and store their
ids in an array..

any help in this regards is appreciated...


The poor way of doing it is...

class V(E):
check = []
def __init__(self):
print id(self)
self.check.append(id(self))
self.val = None

The reason it is poor is because if an object is deleted, its id could
be reused.

Instead, you should use weak references. I've found the following to be
useful on occasion...

import weakref

class V(E):
check = {}
def __init__(self):
#create a weak reference to yourself
#place it in the __olist
self.check[id(self)] = weakref.ref(self)
def __del__(self):
del self.check[id(self)]
def __repr__(self):
return str(id(self))
def get_olist(self):
#this creates a hard reference to every object
return [o() for o in self.check.values() if o() is not None]

- Josiah
Jul 18 '05 #2

P: n/a
Josiah Carlson wrote:
BALAJI RAMAN wrote:
Hello everybody!!!

I'm pretty much new to this OOP...

I have a problem..

Here is a part of code that I'm writing

class V(E):
""" This is a variable for MPY"""
def __init__(self):
print id(self)
check=[]
check.append(id(self))
self.val = None

what I do is call say v1=V() so it means that v1 belongs to the
variable class..

Again if I call v2=V() so now v2 also belong to this class.. I want
to keep a track of all the instances of this class.. and store their
ids in an array..

any help in this regards is appreciated...


The poor way of doing it is...

class V(E):
check = []
def __init__(self):
print id(self)
self.check.append(id(self))
self.val = None

The reason it is poor is because if an object is deleted, its id could
be reused.

Instead, you should use weak references. I've found the following to be
useful on occasion...

import weakref

class V(E):
check = {}
def __init__(self):
#create a weak reference to yourself
#place it in the __olist
self.check[id(self)] = weakref.ref(self)
def __del__(self):
del self.check[id(self)]
def __repr__(self):
return str(id(self))
def get_olist(self):
#this creates a hard reference to every object
return [o() for o in self.check.values() if o() is not None]

- Josiah


The __del__ method may not always be called. I find the WeakValueDictionary
handy (which internally uses callbacks I think).

import weakref

class V:
all = weakref.WeakValueDictionary() # required
def __init__(self, name):
self.name = name
V.all[id(self)] = self # required
def __str__(self):
return self.name
__repr__ = __str__

v1 = V("v1")
v2 = V("v2")
print V.all.values()
del v1
print V.all.values()

Peter
Jul 18 '05 #3

P: n/a
> The __del__ method may not always be called. I find the WeakValueDictionary
handy (which internally uses callbacks I think).


OOO, even better, use the weakref standard method for doing it.

I haven't done extensive testing, but on those occasions where I've used
the class I provided earlier, everything eventually got deleted. It was
likely a function of the object heirarchy and interaction in my tests
and applications. That is, not likely to be duplicated by any sane
person *wink*.

- Josiah
Jul 18 '05 #4

P: n/a
Thanks for all the initial help....

Sorry for bugging you again...

Here is a part of my code..

Suppose if some body wants to assign an e=E() to an expression class..

he may define then e=v+v1(where v and v1 both belong to a variable class)

now again if we define say v2=V() and then try to multiply v2 with e then I want
to raise an error that it is a nonlinear term..

So what I though was if i keep track of all the instances id then I might raise
an exception...

But the problem was i couldnt check the right side of an assigment...

Can the right side of an assignment be checked...
class E:
def __init__(self):
print "E",id(self)

def __add__(self,e2):
e = E()
e.operator = '+'
e.left = self
e.right = e2
return e

def __sub__(self,e2):
e = E()
e.operator = '-'
e.left = self
e.right = e2
return e

def __mul__(self,m2):
e = E()
e.operator = '*'
e.left = self
e.right = m2
return e

def __div__(self,d1):
e = E()
e.operator = '/'
e.left = self
e.right = d1
return e
def __str__(self):
return str(self.left) + self.operator + str(self.right)
check=[]
class V(E):
""" This is a variable for MPY"""
def __init__(self):
print id(self)
check.append(id(self))
self.val = None
def __mul__(self,m2):
e=E()
if self.__class__ == m2.__class__:
return "non"
else:
e=E()
e.operator = '*'
e.left = self
e.right = m2
return e
--- Balaji
Jul 18 '05 #5

P: n/a
Balaji wrote:
Thanks for all the initial help....

Sorry for bugging you again...

Here is a part of my code..

Suppose if some body wants to assign an e=E() to an expression class..

he may define then e=v+v1(where v and v1 both belong to a variable class)

now again if we define say v2=V() and then try to multiply v2 with e then I want
to raise an error that it is a nonlinear term..

So what I though was if i keep track of all the instances id then I might raise
an exception...

But the problem was i couldnt check the right side of an assigment...

Can the right side of an assignment be checked...


You can intercept the process of assignment.
In older python, this was done overwriting __setattr__,
but today it is much simpler and cleaner to user property
objects. You can just define a setter that does certain checks.
print property.__doc__ property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del'ing, an
attribute. Typical use is to define a managed attribute x:
class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")


ciao - chris

--
Christian Tismer :^) <mailto:ti****@stackless.com>
Mission Impossible 5oftware : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jul 18 '05 #6

P: n/a
Balaji wrote:
Suppose if some body wants to assign an e=E() to an expression class..
he may define then e=v+v1(where v and v1 both belong to a variable class)
now again if we define say v2=V() and then try to multiply v2 with e then
I want to raise an error that it is a nonlinear term..

So what I though was if i keep track of all the instances id then I might
raise an exception...

But the problem was i couldnt check the right side of an assigment...


I'm not sure what you mean - my guess is entirely different from Christan's
- but anyway:

I suppose you want an expression

a operator b

to either raise an exception or return a new expression and base this
decision on both the kind of a and b. You can do this by providing a lookup
table with all allowed operations (or all forbidden ops, if that is
significantly smaller). Here's the simplest implementation I could think
of:

<expr.py>
import sets

supported = sets.Set([
# operation, leftoperand, rightoperand
("+","v", "v"),
("+","+", "v"),
("+","v", "+"),
("+","+", "+"),
("*","v", "v"),
# complete with all allowed
# combinations of operators/values
])

class Base:
"""Shared implementation for Expressions and Values """
def op(self, operator, other):
if (operator, self.operator, other.operator) in supported:
return Expression(operator, self, other)
else:
raise ValueError("unsupported operation")

def __add__(self, other):
return self.op("+", other)

def __mul__(self, other):
return self.op("*", other)

# add __div__ etc. here

class Expression(Base):
def __init__(self, operator, left, right):
self.operator = operator
self.left = left
self.right = right

def __str__(self):
return str(self.left) + self.operator + str(self.right)

class Value(Base):
operator = "v"
def __init__(self, value):
self.value = value
def __str__(self):
return "Value(%s)" % self.value

if __name__ == "__main__":
print Value(3) * Value(4)
print Value(1) + Value(2) + Value(3)
print Value(1) + Value(2) * Value(3) # will raise an exception
</expr.py>
Peter

Jul 18 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.