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

Suggesting for overloading the assign operator

P: n/a
Rim
Hi,

I have been thinking about how to overload the assign operation '='.
In many cases, I wanted to provide users of my packages a natural
interface to the extended built-in types I created for them, but the
assign operator is always forcing them to "type cast" or coerce the
result when they do a simple assign for the purpose of setting the
value of a variable. Borrowing an example from this newgroup, the
second assignment below ereases all Currency knowledge from variable
'c', when the user only wanted to update the value of c, not its type:

c=Currency(5)
c=7

I fully understand the workaround of doing c=Curreny(7) instead, but
users don't want to be bothered with that.

I read some of the prior discussions, but I did not see a suggestion
for permanent a solution. I would like to propose the following.

The idea is to separate the value assignment from the type assignment,
by introducing a new operator, let's say the ':=' operator.

'=' remains what it is, assigns type and value at the same time
':=' assigns only the value

For example:
class myint(int): pass .... a = myint()
a := 6 type(a)
<class '__main__.myint'> a

6

In reality, := would just coerce the return type of the RHS of := to
the type of the variable on the LHS of the :=, preserving the value(s)
as best as it can.

If the type of the variable was still undefined, ':=' would behave
like '='. It might create confusion in future code, but does not break
old code.

I think it would be a nice feature to have. Comments?

Thanks,
- Rim
Jul 18 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a

"Rim" <ri*******@yahoo.com> wrote in message
news:6f**************************@posting.google.c om...
Hi,

I have been thinking about how to overload the assign operation '='.


Assignment is a statement, not an operator, and therefore not
overloadable . This is an intentional design decision that GvR will
not change.

TJR
Jul 18 '05 #2

P: n/a

"Rim" <ri*******@yahoo.com> wrote in message
news:6f**************************@posting.google.c om...
Hi,

I have been thinking about how to overload the assign operation '='.
In many cases, I wanted to provide users of my packages a natural
interface to the extended built-in types I created for them, but the
assign operator is always forcing them to "type cast" or coerce the
result when they do a simple assign for the purpose of setting the
value of a variable.


Use a property. Changing the semantics of the assignment
statement (NOT assignment operator) is not going to happen.

Properties are new in Python 2.2 (which is around a year
old by now.) They enable you to have getter and setter
methods with an interface that looks like an instance
variable.

John Roth
Jul 18 '05 #3

P: n/a
Rim
"Terry Reedy" <tj*****@udel.edu> wrote in message news:<co********************@comcast.com>...
"Rim" <ri*******@yahoo.com> wrote in message
news:6f**************************@posting.google.c om...
Hi,

I have been thinking about how to overload the assign operation '='.


Assignment is a statement, not an operator, and therefore not
overloadable . This is an intentional design decision that GvR will
not change.


Well, what about the idea of providing another statement, the one I
proposed in the original post?

'=' statement assigns type and value
':=' statement assigns value only

Rim
Jul 18 '05 #4

P: n/a
Rim wrote:
What do you think about providing a statement to assign values
without assigning type?

'=' statement assigns value and type
':=' statement assigns value ony


I think the concept has some merit. I think that sometimes it useful to ensure
that the target of a rebind operation have the same type as the object which was
bound before the rebind.

I know that the same effect can be achieved by descriptors or overriding
"setattr" et al. Or something like this

a = 9
b = 42
if isinstance(b, type(a)):
a = b
else:
raise TypeError("Incompatible types.")

However, these options, i.e. putting type checking logic in "setattr" et al, do
not make it explicit in the code that type enforcement is in place.

Expressing the enforcement syntactically, as Rim suggests, would make it more
explicit for the programmer, as well as providing some extremely useful
optimisation hints, especially for products such as psyco.

Psyco, if I understand it correctly, generates machine code for all paths
through a suite, depending on the types of the objects manipulated in the suite.
Such explicitly stated type enforcement would provide valuable information to
optimisers.

Not that I'm proposing that the OPs solution be adopted. Just that I think he is
addressing a valid concern.

regards,

--
alan kennedy
-----------------------------------------------------
check http headers here: http://xhaus.com/headers
email alan: http://xhaus.com/mailto/alan
Jul 18 '05 #5

P: n/a
In article <6f**************************@posting.google.com >,
Rim <ri*******@yahoo.com> wrote:

I have been thinking about how to overload the assign operation '='.
In many cases, I wanted to provide users of my packages a natural
interface to the extended built-in types I created for them, but the
assign operator is always forcing them to "type cast" or coerce the
result when they do a simple assign for the purpose of setting the
value of a variable. Borrowing an example from this newgroup, the
second assignment below ereases all Currency knowledge from variable
'c', when the user only wanted to update the value of c, not its type:

c=Currency(5)
c=7

I fully understand the workaround of doing c=Curreny(7) instead, but
users don't want to be bothered with that.


If you have users who don't want to learn Python, give them a special
Python-like language. I won't say it's trivial, but it's not that hard.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Usenet is not a democracy. It is a weird cross between an anarchy and a
dictatorship.
Jul 18 '05 #6

P: n/a
Quoth Rim:
[...]
The idea is to separate the value assignment from the type assignment,
by introducing a new operator, let's say the ':=' operator.

'=' remains what it is, assigns type and value at the same time
':=' assigns only the value
That's a peculiar way of speaking. '=' does not assign type and
value to a variable; it assigns an object to a name.

[...] In reality, := would just coerce the return type of the RHS of := to
the type of the variable on the LHS of the :=, preserving the value(s)
as best as it can.
"The type of the variable" is not a meaningful phrase in Python:
names do not have types; objects do. I assume you meant "the type
of the object the name on the lhs is presently bound to".

Coerce how? Do you want a new __magicmethod__ for this operation?

Would ':=' mutate the object presently bound to the lhs name
create a new object and rebind the lhs name? To be concrete:

a = whatever
b = a
a := 7
assert a is b

Should that assertion succeed or fail, in general? (Note that it
fails in general if the ':=' is replaced with '=', even if
whatever == 7.)

Would ':=' support chaining? That is, would
a := b := <some expression>
work? If so, would it be equivalent to
_tmp = <some expression>
a := _tmp
b := _tmp
(except for the namespace pollution), to match the semantics of
chained '='? (Note that the assignments happen left to right.)

Would use of a name on the lhs of a ':=' cause that name to be
considered local, as such use with '=' does?
If the type of the variable was still undefined, ':=' would behave
like '='. It might create confusion in future code, but does not break
old code.
Yikes. Why not raise NameError if the name on the lhs of ':=' is
not yet bound?
I think it would be a nice feature to have. Comments?


Your example
a = Currency(6)
a := 7
is highly strange. (Even if we ignore the question of *which*
currency is being represented; the example could easily be
restated with, say, FixedPoint or Rational or some such.)

How is it that your users are happy to write Currency(...) when
first assigning to a name, but not happy doing so when assigning
later?

Do they not understand that '=' binds a name to an object? Are
they C programmers who think of assignment as copying a value from
one location in memory to another? Do they think of the first
assignment as a type declaration for the name? (If any of these
three are true, they need to be better educated -- they're all
fundamental misconceptions about Python.)

Do they need a language with syntactic support for Currency
objects?

--
Steven Taschuk st******@telusplanet.net
"Our analysis begins with two outrageous benchmarks."
-- "Implementation strategies for continuations", Clinger et al.

Jul 18 '05 #7

P: n/a

"John Roth" <jo******@ameritech.net> wrote in message
news:vg************@news.supernews.com...

"Rim" <ri*******@yahoo.com> wrote in message
news:6f**************************@posting.google.c om...
Hi,

I have been thinking about how to overload the assign operation '='.
In many cases, I wanted to provide users of my packages a natural
interface to the extended built-in types I created for them, but the
assign operator is always forcing them to "type cast" or coerce the
result when they do a simple assign for the purpose of setting the
value of a variable.
Use a property. Changing the semantics of the assignment
statement (NOT assignment operator) is not going to happen.

Properties are new in Python 2.2 (which is around a year
old by now.) They enable you to have getter and setter
methods with an interface that looks like an instance
variable.

John Roth


I usually don't reply to my own posts, but I thought it
might be nice if I put up a skeletal example of how to do it.

I'm assuming that what you want is a way of insuring, in a
class named Foo, that the variable fooBar is always bound
to a class instance of Bar, regardless of what the user tries
to assign to it.

Most of what follows is documented in "What's New in Python 2.2,"
section 2: Peps 252 and 253: Type and Class Changes.

The information on the __new__ method is in the document
under 2.5: Related Links.

The way to do this is:

1. Both Foo and Bar have to inherit from a built-in type.
That's usually "object", but it can be any built-in type.

2. Refactor Foo so that all references to self.fooBar
now refer to self._fooBar. (It can be any name; the
underscore is a convention that means "private."

3. Insert the following code in Foo:

def _getFooBar(self):
return self._fooBar

def _setFooBar(self, parm):
self._fooBar = Bar(parm)

_fooBar = property(_setFooBar, _getFoobar, None, "doc strings swing")

4. In class Bar, use the __new__ method to check if
the parameter is an instance of class Bar. If it is, return that
instance, otherwise call your superclass's __new__ method
to create a new object and return it.

5. In class Bar, do whatever type determination you need to
in the __init__ method to build your new Bar object.

Most of this is documented in "What's New in Python 2.2,"
section 2: Peps 252 and 253: Type and Class Changes.

The information on the __new__ method is in the document
under 2.5: Related Links.

HTH

John Roth

Jul 18 '05 #8

P: n/a
On Mon, 2003-06-30 at 20:31, Rim wrote:
The idea is to separate the value assignment from the type assignment,
by introducing a new operator, let's say the ':=' operator.

'=' remains what it is, assigns type and value at the same time
':=' assigns only the value


On the surface, this idea seems appealing. However, besides the
arguments that others have forwarded, you might consider the fact that
given two similar "assignment operators", subtle bugs are bound to
arise.
class myint(int): pass ... a = myint()
a := 6 type(a)
<class '__main__.myint'> a

6


What if the programmer accidentally uses '=' rather than ':=' (and I
think this would be a natural mistake)? It would be legal Python but
would probably not have the intended effect. It is not unlike the
"allow assignment in expressions" arguments that come up here every 3.2
weeks.

Anyway, your arguments cancel themselves out. You asked initially for a
way to overload '=' because your users didn't want to have to type
something different. But ':=' *is* different, so what are you really
looking for?. Worse, because ':=' isn't *very* different, it makes
mistakes more likely.

In short, I think using a = myint(6) or even a.value = 6 is preferable.
Besides, when I used Pascal (many years ago), I found ':=' to be one of
the most annoying (and most common) things I had to type. Please don't
ask to bring it back.
Regards,

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 (800) 735-0555
Jul 18 '05 #9

P: n/a
On Tue, 2003-07-01 at 11:01, Alan Kennedy wrote:
Not that I'm proposing that the OPs solution be adopted. Just that I think he is
addressing a valid concern.


I agree that it is a valid concern. I think, however, that other valid
concerns outweigh this one. I suspect you think so as well, otherwise
you would have omitted the first sentence.

Regards,

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 (800) 735-0555
Jul 18 '05 #10

P: n/a
On Tue, 2003-07-01 at 13:01, Alan Kennedy wrote:
Rim wrote:
What do you think about providing a statement to assign values
without assigning type?

'=' statement assigns value and type
':=' statement assigns value ony


I think the concept has some merit. I think that sometimes it useful to ensure
that the target of a rebind operation have the same type as the object which was
bound before the rebind.

I know that the same effect can be achieved by descriptors or overriding
"setattr" et al. Or something like this


Or maybe:

class stricttype(object):

counter = 1

def __init__(self, required_type, doc=None, real_attr=None):
self.required_type = required_type
if not real_attr:
real_attr = '_stricttype_attr_%i' % stricttype.counter
stricttype.counter += 1
self.real_attr = real_attr
self.doc = doc

def __set__(self, obj, value):
if not isinstance(value, self.required_type):
raise TypeError, 'must be of type %r' % self.required_type
setattr(obj, self.real_attr, value)

def __get__(self, obj, cls):
return getattr(obj, self.real_attr)

def __del__(self, obj):
delattr(obj, self.real_attr)

def __doc__(self, obj):
return self.doc
class IntPoint(object):

def __init__(self, x, y):
self.x = x
self.y = y

def __str__(self):
return 'Point: (%i, %i)' % (self.x, self.y)

x = stricttype(int)
y = stricttype(int)
p = IntPoint(1, 1)
p Point: (1, 1) p.x = 2
p Point: (2, 1) p.x = 2.2

Traceback (most recent call last):
File "stricttype.py", line 44, in ?
p.x = 2.2
File "stricttype.py", line 15, in __set__
raise TypeError, 'must be of type %r' % self.required_type
TypeError: must be of type <type 'int'>
If we're talking about optimizations, there's no reason something like
Psyco couldn't specifically look for specific descriptors like
stricttype, and probably replace that implementation with something
better optimized.

Ian

Jul 18 '05 #11

P: n/a
On Tue, 1 Jul 2003 09:22:03 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth Rim:
[...]
The idea is to separate the value assignment from the type assignment,
by introducing a new operator, let's say the ':=' operator.

'=' remains what it is, assigns type and value at the same time
':=' assigns only the value
That's a peculiar way of speaking. '=' does not assign type and
value to a variable; it assigns an object to a name.

[...]
In reality, := would just coerce the return type of the RHS of := to
the type of the variable on the LHS of the :=, preserving the value(s)
as best as it can.


"The type of the variable" is not a meaningful phrase in Python:
names do not have types; objects do. I assume you meant "the type
of the object the name on the lhs is presently bound to".

Coerce how? Do you want a new __magicmethod__ for this operation?

Would ':=' mutate the object presently bound to the lhs name
create a new object and rebind the lhs name? To be concrete:

One thought would be that it wouldn't change the current binding. E.g.,

x := y

could be a spelling of x.__update__(y) and would be an *expression* with
potential side effects. By convention, a reference to the updated same object
would be returned. I.e., x.__class__ would have to have

def __update__(self, other):
<optional use of other>
return self

For starters, you could just let AttributeError get raised if there's no __update__ method.
a = whatever
b = a
a := 7
assert a is b

Should that assertion succeed or fail, in general? (Note that it
fails in general if the ':=' is replaced with '=', even if
whatever == 7.)
For the above, it should succeed, since the binding will have been unchanged
Would ':=' support chaining? That is, would
a := b := <some expression>
work? If so, would it be equivalent to Yes, it should work, but no, it wouldn't be equivalent to _tmp = <some expression>
a := _tmp
b := _tmp working left to right, it would presumably be equivalent to

a.__update__(b).__update__(<some expression>)
(except for the namespace pollution), to match the semantics of
chained '='? (Note that the assignments happen left to right.)

Would use of a name on the lhs of a ':=' cause that name to be
considered local, as such use with '=' does? No, because it would be a named object reference for the purpose of looking
up the __update__ attribute in the non-sugar spelling of a:=b (which
is a.__update__(b)) -- i.e., it's an expression, not really an assignment statement.
If the type of the variable was still undefined, ':=' would behave
like '='. It might create confusion in future code, but does not break
old code.
Yikes. Why not raise NameError if the name on the lhs of ':=' is
not yet bound?

Yes.
I think it would be a nice feature to have. Comments?
Your example
a = Currency(6)
a := 7
is highly strange. (Even if we ignore the question of *which*
currency is being represented; the example could easily be
restated with, say, FixedPoint or Rational or some such.)

I don't know that I would totally dismiss the usage. It could be
a concise notation for a possibly polymorphic update operation.

w = Widget(blah, blah)
w := ('blue','white') # changes fg/bg colors
w := (20,40) # changes position
w := Font('Times Roman', size=24)
w := 'some text appended to a text widget'

Of course, you could use a property very similarly, e.g.,
w.p = 'text ...'

I guess it's a matter of what kind of sugar you like ;-)
How is it that your users are happy to write Currency(...) when
first assigning to a name, but not happy doing so when assigning
later?

Do they not understand that '=' binds a name to an object? Are
they C programmers who think of assignment as copying a value from
one location in memory to another? Do they think of the first
assignment as a type declaration for the name? (If any of these
three are true, they need to be better educated -- they're all
fundamental misconceptions about Python.) True, but if they did understand that a=b binds but a:=b updates??

Do they need a language with syntactic support for Currency
objects?

I'm not sure what that would mean.

OTOH, a:=b might lead to analogies with a+=b and other a<op>=b
and then where would we be ;-)

Let's see...

a+:=b => a.__update__(a.__add__(b))

?? ;-)

Regards,
Bengt Richter
Jul 18 '05 #12

P: n/a
Quoth Bengt Richter:
[...suggests a := b equivalent to a.__update__(b)...]
I guess it's a matter of what kind of sugar you like ;-)
Quite.

[...syntactic support for Currency objects...] I'm not sure what that would mean.


I meant a language like Python but with a Currency literal syntax.
With syntax such as, say,
123.45$ equivalent to Currency(123.45)
(except, perhaps, for decimal vs binary exactness issues), the
users could type
a = 7$
# ...
a = 6$
which is less onerous than writing Currency(7), Currency(6).

This idea is well-suited to the scenario in which the users make
pervasive use of objects of this type, and the main problem is
having to type "Currency" over and over again.

[...]
--
Steven Taschuk st******@telusplanet.net
"What I find most baffling about that song is that it was not a hit."
-- Tony Dylan Davis (CKUA)

Jul 18 '05 #13

P: n/a
Quoth Bengt Richter:
[...suggests a := b equivalent to a.__update__(b)...]
I guess it's a matter of what kind of sugar you like ;-)
Quite.

[...syntactic support for Currency objects...] I'm not sure what that would mean.


I meant a language like Python but with a Currency literal syntax.
With syntax such as, say,
123.45$ equivalent to Currency(123.45)
(except, perhaps, for decimal vs binary exactness issues), the
users could type
a = 7$
# ...
a = 6$
which is less onerous than writing Currency(7), Currency(6).

This idea is well-suited to the scenario in which the users make
pervasive use of objects of this type, and the main problem is
having to type "Currency" over and over again.

[...]
--
Steven Taschuk st******@telusplanet.net
"What I find most baffling about that song is that it was not a hit."
-- Tony Dylan Davis (CKUA)

Jul 18 '05 #14

P: n/a
On Wed, 2 Jul 2003 08:21:57 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth Bengt Richter:
[...suggests a := b equivalent to a.__update__(b)...]
I guess it's a matter of what kind of sugar you like ;-)


Quite.

[...syntactic support for Currency objects...]
I'm not sure what that would mean.


I meant a language like Python but with a Currency literal syntax.
With syntax such as, say,
123.45$ equivalent to Currency(123.45)
(except, perhaps, for decimal vs binary exactness issues), the
users could type
a = 7$
# ...
a = 6$
which is less onerous than writing Currency(7), Currency(6).

This idea is well-suited to the scenario in which the users make
pervasive use of objects of this type, and the main problem is
having to type "Currency" over and over again.


Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.

Example, then explanation:

a = 7 .USD # (using symbols from http://www.xe.com/iso4217.htm by convention, no hard defs)
# ...
a = 6 .USD

This example uses the fact that int has no methods with plain names, so 6 .__getattribute__('USD')
will fail. Normally that would be the AttributeError end of it, but if '.' were like '+', we could
look for the r-version of __getattribute__ on the other object, analogous to __radd__. Thus

6 .USD # => USD.__rgetattribute__(6)

(note necessary disambiguating space here is not necessary in unambiguous contexts)
could return a specific currency object, e.g., if USD were defined something like e.g.,
(untested sketch !!)
--
class XXX_Currency(FixedPoint):
def __init__(self, symbol, *valprec):
FixedPoint.__init__(self, *valprec)
self.symbol = symbol
def __rgetattribute__(self, other):
return self.__class__(self.symbol, other, self.get_precision())

USD = XXX_Currency('USD')
--
Alternatively, perhaps USD could be a class from a factory instead of an instance, and have
__rgetattribute__ as a class method.

BTW,

num = 6
num = num.USD

would do the expected. I.e., this would be a dynamic mechanism, not a tweaked literal syntax.

Obviously this could be used for other quantity units than currencies, e.g.,

distance_to_moon = 384467 .km # avg dist

I.e., the mechanism is conceived in terms of an __rgetattribute__ method analogous to __radd__,
where you look for a compatible method in the other if the left arg can't handle it.
This could then allow a general mechanism for all types, not just numerics, yet constrain it
to special methods, to avoid accidental connections. Thus for an int,

6 . USD # => USD.__rgetattr__(6)

but also, this kind of binary-op attribute computation could supply missing methods, e.g.,
for simple file objects. Thus

f.readlines()

would effectively become

readlines.__rgetattribute__(f)()

if there were no readlines method on f, and this could
wrap f on the fly to provide the missing readlines method.

Am I being a troublemaker? ;-)

Regards,
Bengt Richter
Jul 18 '05 #15

P: n/a
Bengt Richter wrote:
Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.
[...lots of interesting examples...]
f.readlines()

would effectively become

readlines.__rgetattribute__(f)()

if there were no readlines method on f, and this could
wrap f on the fly to provide the missing readlines method.


My head spins... I don't know if I should consider these ideas very
powerful -- or very evil... My guts tell me that this could be very
powerful indeed. However my intuition tells me that there is a big
catch about this, but I don't know what it is yet... :-P

--Irmen

Jul 18 '05 #16

P: n/a
On Wed, 2 Jul 2003 08:21:57 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth Bengt Richter:
[...suggests a := b equivalent to a.__update__(b)...]
I guess it's a matter of what kind of sugar you like ;-)


Quite.

[...syntactic support for Currency objects...]
I'm not sure what that would mean.


I meant a language like Python but with a Currency literal syntax.
With syntax such as, say,
123.45$ equivalent to Currency(123.45)
(except, perhaps, for decimal vs binary exactness issues), the
users could type
a = 7$
# ...
a = 6$
which is less onerous than writing Currency(7), Currency(6).

This idea is well-suited to the scenario in which the users make
pervasive use of objects of this type, and the main problem is
having to type "Currency" over and over again.


Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.

Example, then explanation:

a = 7 .USD # (using symbols from http://www.xe.com/iso4217.htm by convention, no hard defs)
# ...
a = 6 .USD

This example uses the fact that int has no methods with plain names, so 6 .__getattribute__('USD')
will fail. Normally that would be the AttributeError end of it, but if '.' were like '+', we could
look for the r-version of __getattribute__ on the other object, analogous to __radd__. Thus

6 .USD # => USD.__rgetattribute__(6)

(note necessary disambiguating space here is not necessary in unambiguous contexts)
could return a specific currency object, e.g., if USD were defined something like e.g.,
(untested sketch !!)
--
class XXX_Currency(FixedPoint):
def __init__(self, symbol, *valprec):
FixedPoint.__init__(self, *valprec)
self.symbol = symbol
def __rgetattribute__(self, other):
return self.__class__(self.symbol, other, self.get_precision())

USD = XXX_Currency('USD')
--
Alternatively, perhaps USD could be a class from a factory instead of an instance, and have
__rgetattribute__ as a class method.

BTW,

num = 6
num = num.USD

would do the expected. I.e., this would be a dynamic mechanism, not a tweaked literal syntax.

Obviously this could be used for other quantity units than currencies, e.g.,

distance_to_moon = 384467 .km # avg dist

I.e., the mechanism is conceived in terms of an __rgetattribute__ method analogous to __radd__,
where you look for a compatible method in the other if the left arg can't handle it.
This could then allow a general mechanism for all types, not just numerics, yet constrain it
to special methods, to avoid accidental connections. Thus for an int,

6 . USD # => USD.__rgetattr__(6)

but also, this kind of binary-op attribute computation could supply missing methods, e.g.,
for simple file objects. Thus

f.readlines()

would effectively become

readlines.__rgetattribute__(f)()

if there were no readlines method on f, and this could
wrap f on the fly to provide the missing readlines method.

Am I being a troublemaker? ;-)

Regards,
Bengt Richter
Jul 18 '05 #17

P: n/a
Bengt Richter wrote:
Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.
[...lots of interesting examples...]
f.readlines()

would effectively become

readlines.__rgetattribute__(f)()

if there were no readlines method on f, and this could
wrap f on the fly to provide the missing readlines method.


My head spins... I don't know if I should consider these ideas very
powerful -- or very evil... My guts tell me that this could be very
powerful indeed. However my intuition tells me that there is a big
catch about this, but I don't know what it is yet... :-P

--Irmen

Jul 18 '05 #18

P: n/a
On Wed, 2003-07-02 at 15:09, Bengt Richter wrote:
Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.

Example, then explanation:

a = 7 .USD # (using symbols from http://www.xe.com/iso4217.htm by convention, no hard defs)
# ...
a = 6 .USD


Does 7 .USD *really* look that much better than USD(7)? And, really,
how often do you need currency literals? All my currency values come
from non-literal sources -- databases and XML files, an excel
spreadsheet, etc. I don't think this objection is particular to
currency either -- for most types this is true. If you are using them a
lot, you are acquiring them from non-code sources.

Though I suppose Rebol would be a counterexample. And, in the case of
scripting (a kind of programming, not a kind of programming language :)
it might be a more valid need. But most of Rebol's interesting data
types aren't syntactically valid in Python anyway.

Ian

Jul 18 '05 #19

P: n/a
Rim
Everyone! Thanks a lot for the insightful and enlightening discussion.

I think the suggestion to solve the problem by using the __setattr__
special method will not work because it intercepts attribute
assignment of the form "self.attr = somthing", and not what I want,
which is "name = something".

John suggested to look at properties, this is the closest I can get to
the
behavior I am looking for, but from my understanding, that will let me
intercept "name.value = something" instead of intercepting "name =
something".

Thank you very much everyone.
- Rim
Jul 18 '05 #20

P: n/a
On Wed, 2003-07-02 at 15:09, Bengt Richter wrote:
Hm, it just occurred to me that one could have yet another form of sugar
[ It's now later, and I think this may be more than sugar ;-) ]
to help with this, by treating the dot operator slightly more symmetrically,
like, e.g., '+'.

Example, then explanation:

a = 7 .USD # (using symbols from http://www.xe.com/iso4217.htm by convention, no hard defs)
# ...
a = 6 .USD


Does 7 .USD *really* look that much better than USD(7)? And, really,
how often do you need currency literals? All my currency values come
from non-literal sources -- databases and XML files, an excel
spreadsheet, etc. I don't think this objection is particular to
currency either -- for most types this is true. If you are using them a
lot, you are acquiring them from non-code sources.

Though I suppose Rebol would be a counterexample. And, in the case of
scripting (a kind of programming, not a kind of programming language :)
it might be a more valid need. But most of Rebol's interesting data
types aren't syntactically valid in Python anyway.

Ian

Jul 18 '05 #21

P: n/a
Rim
Everyone! Thanks a lot for the insightful and enlightening discussion.

I think the suggestion to solve the problem by using the __setattr__
special method will not work because it intercepts attribute
assignment of the form "self.attr = somthing", and not what I want,
which is "name = something".

John suggested to look at properties, this is the closest I can get to
the
behavior I am looking for, but from my understanding, that will let me
intercept "name.value = something" instead of intercepting "name =
something".

Thank you very much everyone.
- Rim
Jul 18 '05 #22

P: n/a
ri*******@yahoo.com (Rim) wrote in message news:<6f**************************@posting.google. com>...
Everyone! Thanks a lot for the insightful and enlightening discussion.

I think the suggestion to solve the problem by using the __setattr__
special method will not work because it intercepts attribute
assignment of the form "self.attr = somthing", and not what I want,
which is "name = something".

John suggested to look at properties, this is the closest I can get to
the
behavior I am looking for, but from my understanding, that will let me
intercept "name.value = something" instead of intercepting "name =
something".

Thank you very much everyone.
- Rim


Okay, you asked for it ;)

class MetaTrick(type):
def __init__(cls,name,bases,dic):
super(MetaTrick,cls).__init__(name,bases,dic)
for (k,v) in dic.iteritems():
if not k.endswith("__"): setattr(cls,k,v)
def __setattr__(cls,k,v):
print "Intercepting %s = %s" % (k,v)
super(MetaTrick,cls).__setattr__(k,v)

class C:
__metaclass__=MetaTrick
name='something'

This gives the output "Intercepting name = something".

I show you this snippet hoping you will not use it!

nothing-is-impossible-with-metaclasses-ly,

Michele
Jul 18 '05 #23

P: n/a
In article <6f**************************@posting.google.com >,
Rim <ri*******@yahoo.com> wrote:

I think the suggestion to solve the problem by using the __setattr__
special method will not work because it intercepts attribute
assignment of the form "self.attr = somthing", and not what I want,
which is "name = something".


Why don't you follow my suggestion about creating your own language?
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Usenet is not a democracy. It is a weird cross between an anarchy and a
dictatorship.
Jul 18 '05 #24

P: n/a
Rim
> >I think the suggestion to solve the problem by using the __setattr__
special method will not work because it intercepts attribute
assignment of the form "self.attr = somthing", and not what I want,
which is "name = something".


Why don't you follow my suggestion about creating your own language?


I think it would be too much work for one person, and I don't know
how, and I don't think I have the time. Thanks but for now this is
beyond my limited capabilities!

Rim
Jul 18 '05 #25

P: n/a
You know, I couldn't even figure out what the whole ':=' assignment
did until I saw this message:

bo**@oz.net (Bengt Richter) wrote in message
I don't know that I would totally dismiss the usage. It could be
a concise notation for a possibly polymorphic update operation.

w = Widget(blah, blah)
w := ('blue','white') # changes fg/bg colors
w := (20,40) # changes position
w := Font('Times Roman', size=24)
w := 'some text appended to a text widget'

Of course, you could use a property very similarly, e.g.,
w.p = 'text ...'

I guess it's a matter of what kind of sugar you like ;-)


So what we're talking about here is some form of type driven
assignment? Where you can assign to properties of an object given a
specific type of rhs expression? I guess that could be useful, but it
sounds like it could only apply to a very small set of objects, namely
objects where all the properties have different types. It seems like
adding a new syntax to support a fairly small subset of objects is a
long way to go to make things 'easier'. It looks like it would be easy
to screw up, too. For instance:

class Point(object):
def __init__(self, nx, ny):
self.x = nx
self.y = ny
def __typeassign__(self, whatever):
# some magic #

a = Point(3,4) # so far so good
a := (3,4) # ok, that could work
a := 3 # hmm... will it set x, or y, or x and y, or give an
exception?

or, let's go with the currency example:

class Currency(object):
def __init__(self, cval):
self.amount = cval
self.exchangerate = 1.0
def __typeassign__(self, whatever):
#even better magic #

a = Currency(7)
a := 6 # so does this change the amount, or the exchange rate?

So it looks like the behavior here would be at best unpredictable,
unless you already have a deep understanding of what's going on in the
object. (And if you have a deep understanding of what's going on in
the object, would 'a.amount' be so tricky to use?) Now sure, there
are lots of operations that aren't used by every object, but assigning
values to object attributes is a pretty fundamental part of any object
oriented language, and the way Python does it now seems to work for a
lot of people. From the original example, it looks kind of like you
want to define a sort of user-definable built in type, like integer or
string, where there is always a singular piece of data that may have
special functional attributes but no other data attributes. But in
that case, you wouldn't want to assign it as a regular object, you'd
want to build in a special syntax that Python could use to understand
the built in type, so you would have to have:

a = $7
a = $6

so I guess even that wouldn't work quite the way you want. So for
now, I vote no to adding ':=' assignment. Sorry if this is too basic
a look at this, it takes me a while to wrap my head around this
complicated syntax stuff.
Jul 18 '05 #26

This discussion thread is closed

Replies have been disabled for this discussion.