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

Controlling assignation

P: n/a
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.

Let's say I have
a=A() and I want to write a=5

and I want this to change some internal value of a instead of making a
point to a new object (an int 5)

In other word, I would like to be able to use a=5 instead of a.set(5)

Is that possible?
Jul 19 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Xavier Décoret wrote:
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.

Let's say I have
>>> a=A() and I want to write >>> a=5

and I want this to change some internal value of a instead of making a
point to a new object (an int 5)

In other word, I would like to be able to use a=5 instead of a.set(5)

Is that possible?


Not with simple names, such as "a". You can do it if you assign to an
attribute of an object, such as a.b, by intercepting the assignment call
via __setattr__ or a property.

In Python, anyone reading your code would expect that "a=5" represents a
rebinding of the name "a" to a new object, possibly destroying the old
object, and if you did manage to subvert that you'd just be making your
code unreadable, in the way that overuse of #define to change syntax in
C can make C code (even more) unreadable. Please reconsider why you
want to do that and find a more conventional approach, such as a.set(5).

-Peter
Jul 19 '05 #2

P: n/a

On 13.06.2005, at 15:52, Xavier Décoret wrote:
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.

Let's say I have
a=A() and I want to write a=5 and I want this to change some internal value of a instead of making a
point to a new object (an int 5)

In other word, I would like to be able to use a=5 instead of a.set(5)

Is that possible?


the short answer is: no.

the long answer:

if you write
a=A() an instance of class A is created and bound to the local identifier
'a'. If you later write a=5 the object 5 is reassigned to the same identifier, deleting whatever
value was stored there before. The identifier itself does not impose
any restrictions on the type of instances that can be bound to it.
Binding an instance of class A in the first part, does not make the
identifier of the kind 'can-only-bind-A-instances'. In other words:
identifiers don't have types. Thus, there is no mechanism that allows
to change the binding behavior of identifiers.

As a general advise, don't try to write C++ in python. I think, for
most cases, there are far better solutions than changing the assign
operator anyway... explicit is better than implicit:

If class A has only one dedicate value and no internal state, make it a
construcotr call: a=A(5)
Otherwise, it is worth mentioning the name of the member to set.
IMHO this increases the readability of your source code: a.pressure=5

Cheers,

- harold -

--
"I was born not knowing
and have had only a little time
to change that here and there."
-- Richard Feynman

Jul 19 '05 #3

P: n/a
On Mon, 13 Jun 2005 15:52:14 +0200, Xavier Décoret wrote:
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.

Let's say I have
>>> a=A() and I want to write >>> a=5

and I want this to change some internal value of a instead of making a
point to a new object (an int 5)

In other word, I would like to be able to use a=5 instead of a.set(5)

Is that possible?


I don't know, because I don't understand what you mean.

What is A()? A class or a function? What is a.set()? What does it do?

I'm going to make a wild guess as to what you want to do. You want
something like Pascal records or C structs, right?

py> a = MyCustomShapeClass()
py> print a # calls a.__repr__ for a nice printable representation
[top = 0, bottom = 1, left = 5, right = 20, kind = "rect"]
py> a.kind = "oval"
py> a.bottom = 100
py> print a
[top = 0, bottom = 100, left = 5, right = 20, kind = "oval"]

Is that the sort of thing you are looking for?
--
Steven

Jul 19 '05 #4

P: n/a
On Mon, Jun 13, 2005 at 03:52:14PM +0200, Xavier Décoret wrote:
In other word, I would like to be able to use a=5 instead of a.set(5)


If a(5) is acceptable to you in stead of a=5
you can make your instance callable with the __call__ method:
class A(object):
def __init__(self):
self.var=0
def __call__(self,val=None):
self.var=val

a = A()
a(5)
print a.var # gives 5

egbert
--
Egbert Bouwman - Keizersgracht 197 II - 1016 DS Amsterdam - 020 6257991
================================================== ======================
Jul 19 '05 #5

P: n/a
Xavier Décoret a écrit :
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.

Let's say I have
>>> a=A() and I want to write >>> a=5

and I want this to change some internal value of a instead of making a
point to a new object (an int 5)

In other word, I would like to be able to use a=5 instead of a.set(5)

Is that possible?


Thanks anybody for the answers. It confirms what I understood of Python.
What I wanted to do is something like this:

def change(x,v):
x = v

class A(object):
def __init__(self,v):
self.x = v

a = A(3)
print a.x # displays 3
change(a.x,4)
print a.x # still displays 3
It may seem weird, but I ensure there is a reason for doing this. In C++
(the language I am mot familiar with), I could define f to take a
pointer to member function of a class, a pointer and a value and achieve
what I want. In python, I cannot that way becauswe when change(a.x,4) is
executed, a.x is "replaced" by ist value (returned by __getattribute__).

Finally, here is how I hold the situation:
class Handle:
def __init__(self,v):
self.__v = v
def __call__(self):
x = self.__v
while callable(x): x=x()
return x
def set(self,v):
self.__v = v

class HandledProperty(object):
def __init__(self,name=""):
self.name = name
def __get__(self,o,t):
return o.__dict__[self]
def __set__(self,o,v):
o.__dict__[self] = Handle(v)

class A(object):
x = HandledProperty("x")
def __init__(self,v):
self.x = v

def change(x,v):
x.set(v)
a = A(3)
print a.x() # displays 3 (notice the () in the call)
change(a.x,4)
print a.x() # still displays 4
Jul 19 '05 #6

P: n/a
On Mon, 13 Jun 2005 15:52:14 +0200, Xavier Décoret
<Xa************@imag.fr> declaimed the following in comp.lang.python:
I would like to know if there is for python's classes an equivalent of
the operator= that can be overidden.
First problem: = is NOT an "operator", as such.
Let's say I have
>>> a=A()

Assuming A() is creating an instance of some class, the above
basically says: Create a class instance somewhere in memory (note: it
has no identifier at this time, just that the runtime knows where it is
created); Stick the identifier "a" onto that instance.
and I want to write >>> a=5

As before: Create an instance of an integer "5" somewhere in
memory (actually, the first 100 or so integers are pre-created); realize
there is an identifier "a" already in the system, find that identifier,
remove it from whatever it was attached to, and stick it to the new "5".

IOW: the identifier on the left doesn't take part in the
activities until /after/ the right hand side has been computed. The
identifier is then attached (like a 3M Post-It note) to the object that
resulted from the computation of the right hand side.

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Jul 19 '05 #7

P: n/a
Xavier Décoret wrote:
What I wanted to do is something like this:

def change(x,v):
x = v

class A(object):
def __init__(self,v):
self.x = v

a = A(3)
print a.x # displays 3
change(a.x,4)
print a.x # still displays 3
How about this?

def change(x, v):
x.x = v

Then call it with

change(a, 4)

And print a.x will return 4 as you wish.
It may seem weird, but I ensure there is a reason for doing this. In C++
(the language I am mot familiar with), I could define f to take a
pointer to member function of a class, a pointer and a value and achieve
what I want.


In Python the closest match to this might be to pass the reference to
the object, plus the *name* of the attribute, as a string.

def change(obj, attr, v):
setattr(obj, attr, v)

This, of course, is now a useless function since that's what "setattr"
already does...

So:

a = A(3)
print a.x # displays 3
setattr(a, 'x', 4)
print a.x # displays 4

-Peter
Jul 19 '05 #8

P: n/a

"harold fellermann" <ha***************@upf.edu> wrote in message
news:73******************************@upf.edu...
if you write
>>> a=A()an instance of class A is created and bound to the local identifier 'a'.
I think it perhaps better to think of the label 'a' being bound to the
object rather than vice versa. For one, a label can only be bound (stuck
to, like a stick note) to one object at a time while one object can have
many labels (and other references) stuck to it.
If you later write a=5
the object 5 is reassigned to the same identifier,


Or one could say that the label 'a' is removed from the A() object and
reassigned to the 5 object. Since the 5 object may have numerous other
connections, and since those connections are unaffected by the new
connection to 'a', whereas the previous assignment of 'a' is broken, I
think it better to say that 'a' is being reassigned, not 5.
deleting whatever value was stored there before.
In memory-oriented languages, such as C, names refer to chunks of memory
where values are stored and deleted. Assigning a new value to a variable
puts a new value in that chunk of memory, necessarily overwriting the old.

In object-oriented Python, objects have values and possibly multiple
associations with names and slots. If, but only if, 'a' was the last
association of its last assigned-to object, then that object is eligible
for deletion.
In other words: identifiers don't have types.


This and the following I agree with.

Terry J. Reedy

Jul 19 '05 #9

P: n/a

On 13.06.2005, at 19:23, Terry Reedy wrote:

"harold fellermann" <ha***************@upf.edu> wrote in message
news:73******************************@upf.edu...
if you write
> a=A()

an instance of class A is created and bound to the local identifier
'a'.


I think it perhaps better to think of the label 'a' being bound to the
object rather than vice versa. For one, a label can only be bound
(stuck
to, like a stick note) to one object at a time while one object can
have
many labels (and other references) stuck to it.
If you later write
> a=5

the object 5 is reassigned to the same identifier,


Or one could say that the label 'a' is removed from the A() object and
reassigned to the 5 object. Since the 5 object may have numerous other
connections, and since those connections are unaffected by the new
connection to 'a', whereas the previous assignment of 'a' is broken, I
think it better to say that 'a' is being reassigned, not 5.


yeah. I have never seen it this way, but you are right! Binding the
identifier/label to the object is a much better perspective. thanks for
the lesson :)

- harold -
--
Ceci n'est pas une signature.
--

Jul 19 '05 #10

P: n/a
Xavier Décoret a écrit :
(snip)
What I wanted to do is something like this:

def change(x,v):
x = v

class A(object):
def __init__(self,v):
self.x = v

a = A(3)
print a.x # displays 3
change(a.x,4)
print a.x # still displays 3
It may seem weird,
It does
but I ensure there is a reason for doing this.
I really wonder what it can be ???
In C++
(the language I am mot familiar with), I could define f to take a
pointer to member function of a class, a pointer and a value and achieve
what I want. In python, I cannot that way becauswe when change(a.x,4) is
executed, a.x is "replaced" by ist value (returned by __getattribute__).

Finally, here is how I hold the situation:
class Handle:
def __init__(self,v):
self.__v = v
def __call__(self):
x = self.__v
while callable(x): x=x()
return x
def set(self,v):
self.__v = v

class HandledProperty(object):
def __init__(self,name=""):
self.name = name
def __get__(self,o,t):
return o.__dict__[self]
def __set__(self,o,v):
o.__dict__[self] = Handle(v)

class A(object):
x = HandledProperty("x")
def __init__(self,v):
self.x = v

def change(x,v):
x.set(v)
a = A(3)
print a.x() # displays 3 (notice the () in the call)
change(a.x,4)
print a.x() # still displays 4


You could achieve the same effect with:

class A( object):
def __init__(self, value):
self.value = value

a = A(3)
a.value = 4
a.value
=> 4

And it's *much* more simple/readable/efficient.

Ever googled for "evolution of a programmer" ?-)
Jul 19 '05 #11

P: n/a
Bruno Desthuilliers a écrit :
Xavier Décoret a écrit :
(snip)
What I wanted to do is something like this:

def change(x,v):
x = v

class A(object):
def __init__(self,v):
self.x = v

a = A(3)
print a.x # displays 3
change(a.x,4)
print a.x # still displays 3
It may seem weird,

It does
but I ensure there is a reason for doing this.

I really wonder what it can be ???


It's the ability to develop the equivalent of GeoNext (and much more) in
Python with a very nice syntax.

You could achieve the same effect with:

class A( object):
def __init__(self, value):
self.value = value

a = A(3)
a.value = 4
a.value
=> 4

Of course, and even simpler ;-)
print "4"

More seriously, try to do this with your simpler approach.

a = A(4)
b = A(lambda : a.x+5)
a.x = 2

print b.x # I want this to be 7, not 9

And it's *much* more simple/readable/efficient.

Ever googled for "evolution of a programmer" ?-)

Not to brag, but I think I know what programming is. Google for my
name. C'est bien un commentaire de francais ca ;-)

Jul 19 '05 #12

P: n/a

"Xavier Décoret" <Xa************@imag.fr> wrote in message
news:42**************@imag.fr...
class A( object):
def __init__(self, value):
self.value = value
More seriously, try to do this with your simpler approach.
a = A(4)
b = A(lambda : a.x+5)
a.x = 2
print b.x # I want this to be 7, not 9


As written, it will be neither, since b.x is a function. But if you call
it, its value *is* 7, not 9, as you specified wanting. So I don't
understand your point.
class A: .... def __init__(self,val): self.x = val
.... a = A(4)
b = A(lambda : a.x+5)
a.x=2
b.x <function <lambda> at 0x008D1650> b.x()

7

Terry J. Reedy


Jul 19 '05 #13

P: n/a
Xavier Décoret a écrit :
Bruno Desthuilliers a écrit :
(snip)
I really wonder what it can be ???


It's the ability to develop the equivalent of GeoNext (and much more) in
Python with a very nice syntax.


This is nice, but this does not explain the why of your code snippet.

You could achieve the same effect with:

class A( object):
def __init__(self, value):
self.value = value

a = A(3)
a.value = 4
a.value
=> 4


Of course, and even simpler ;-)
print "4"


of course !-)
More seriously, try to do this with your simpler approach.

a = A(4)
b = A(lambda : a.x+5)
a.x = 2

print b.x # I want this to be 7, not 9
I may miss the point, but what about:

class A(object):
def __init__(self, x):
self.x = x

def _getx(self):
if callable(self._x):
return self._x()
else:
return self._x

def _setx(self, x):
self._x = x

x = property(_getx, _setx)

a = A(4)
b = A(lambda : a.x+5)
a.x = 2
print "b.x is", b.x

<have-fun with="lambdas">
#... and now for the fine part:
del a
b.x

But what, your solution behaves just the same.
</have-fun>

Ever googled for "evolution of a programmer" ?-)

Not to brag, but I think I know what programming is.


I don't have any reason to doubt it. But do you know what not
programming is ?-)
C'est bien un commentaire de francais ca ;-)


<gaston>Meuhnon</gaston>
Jul 19 '05 #14

P: n/a
On Mon, 13 Jun 2005 15:52:14 +0200, =?ISO-8859-1?Q?Xavier_D=E9coret?= <Xa************@imag.fr> wrote:
<...OTT [OT Title] posted text snipped.../>
assignation != assignment ;-)

Regards,
Bengt Richter
Jul 19 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.