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

Can I reference 1 instance of an object by more names ?

P: n/a
hello,

I'm trying to build a simple functional simulator for JAL (a Pascal-like language for PICs).
My first action is to translate the JAL code into Python code.
The reason for this approach is that it simplifies the simulator very much.
In this translation I want to keep the JAL-syntax as much as possible intact,
so anyone who can read JAL, can also understand the Python syntax.

One of the problems is the alias statement, assigning a second name to an object.
I've defined a class IO_port,
and I create an instance of that port with the name port_D

port_D = IO_port('D')

Now I want to assign a more logical name to that port,
(In JAL: "var byte My_New_Name IS port_D")

Is that possible ?

I think the answer is "no",
because the object itself is not mutable.
Am I right ?

But I read: "An object can have any number of names, or no name at all."
So am I wrong ?

Sorry this has been discussed before, but I'm totally confused.

thanks,
Stef Mientki

May 22 '07 #1
Share this Question
Share on Google+
28 Replies


P: n/a
Stef Mientki said unto the world upon 05/22/2007 07:44 PM:
hello,

I'm trying to build a simple functional simulator for JAL (a Pascal-like language for PICs).
My first action is to translate the JAL code into Python code.
The reason for this approach is that it simplifies the simulator very much.
In this translation I want to keep the JAL-syntax as much as possible intact,
so anyone who can read JAL, can also understand the Python syntax.

One of the problems is the alias statement, assigning a second name to an object.
I've defined a class IO_port,
and I create an instance of that port with the name port_D

port_D = IO_port('D')

Now I want to assign a more logical name to that port,
(In JAL: "var byte My_New_Name IS port_D")

Is that possible ?

I think the answer is "no",
because the object itself is not mutable.
Am I right ?

But I read: "An object can have any number of names, or no name at all."
So am I wrong ?

Sorry this has been discussed before, but I'm totally confused.

thanks,
Stef Mientki
Stef,

You can have multiple names pointing to an object. Consider:
>>class Example(object):
.... pass
....
>>c1 = Example()
c2 = c1
id(c1), id(c2)
(136764076, 136764076)
>>c1, c2
(<__main__.Example object at 0x826daac>, <__main__.Example object at
0x826daac>)
>>del(c2)
c1, c2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c2' is not defined
>>c1
<__main__.Example object at 0x826daac>
>>>
HTH,

Brian vdB
May 22 '07 #2

P: n/a

"Stef Mientki" <S.**************@mailbox.kun.nlwrote in message
news:f0***************************@news.speedlinq. nl...
| port_D = IO_port('D')
|
| Now I want to assign a more logical name to that port,
| (In JAL: "var byte My_New_Name IS port_D")
|
| Is that possible ?
|
| I think the answer is "no",
| because the object itself is not mutable.
| Am I right ?

no

| But I read: "An object can have any number of names, or no name at all."
| So am I wrong ?

yes
Believe the docs.
Use the interactive interpreter to try things for yourself:
port_nice_name = port_awkward_name
!

Terry Jan Reedy

May 23 '07 #3

P: n/a
On Wed, 23 May 2007 01:44:22 +0200, Stef Mientki wrote:
Now I want to assign a more logical name to that port, (In JAL: "var
byte My_New_Name IS port_D")

Is that possible ?

I think the answer is "no",
because the object itself is not mutable. Am I right ?

But I read: "An object can have any number of names, or no name at all."
So am I wrong ?

Sorry this has been discussed before, but I'm totally confused.

# oops, we misspelled a name in the official API
# can't change it, so alias it
mispeled_name = IO_port('D')
fixed_name = IO_port('D')
correct_name = mispeled_name

You can test if two names point to the same object with the is operator:
>>mispeled_name is correct_name
True
>>mispeled_name is fixed_name
False

But make sure you really care that they are the same object. In general,
testing for equality is more sensible.
>>1 == 1.0
True
>>1 is 1.0
False
>>"hello world" == ("hello " + "world")
True
>>"hello world" is ("hello " + "world")
False

--
Steven.
May 23 '07 #4

P: n/a
Stef Mientki a écrit :
hello,

I'm trying to build a simple functional simulator for JAL (a Pascal-like
language for PICs).
My first action is to translate the JAL code into Python code.
The reason for this approach is that it simplifies the simulator very much.
In this translation I want to keep the JAL-syntax as much as possible
intact,
so anyone who can read JAL, can also understand the Python syntax.

One of the problems is the alias statement, assigning a second name to
an object.
I've defined a class IO_port,
and I create an instance of that port with the name port_D

port_D = IO_port('D')

Now I want to assign a more logical name to that port,
(In JAL: "var byte My_New_Name IS port_D")

Is that possible ?

I think the answer is "no",
because the object itself is not mutable.
Am I right ?
You're wrong. The fact that an object is mutable or not is totally
irrelevant here. In Python, 'variables' are in fact name=>ref_to_object
pairs in a namespace (while this may not always be technically true, you
can think of namespaces as dicts). So the name is nothing more than
this: a name. And you can of course bind as many names as you want to a
same object.

port_D = IO_port('D')
foo = port_D
bar = foo
bar is port_D
=True
May 23 '07 #5

P: n/a
thanks Guys for your information,

indeed you're all quit right,
but I think I've not correctly described my problem :-(

I need to have 2 (or more) names, that references the same instance of
an object,
and in assigning a value to the object (or to some property in the object),
I need to do extra activities (like changing some global variables).

Now if I use a "container type object", without actual using the index
of the container object,
I get things working OK.
But now I have to use a dummy index, if I use the object in assignments,
see program below.
Is there another way, without using the dummy index, to achieve the same
results ?

thanks,
Stef Mientki

<Python>
class cpu_ports(object):
def __init__(self, value=0):
self._d = value
def __setitem__(self, index, value):
print 'vv'
self._d = value
def __getitem__(self, index):
return self._d
def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1[0] = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2[0] = 26 # assign another value through the other name
print name1, name2 # both reference are OK

name2[0] = name1[0] + 13 # use both names at either side of an assignment
print name1, name2 # both references still OK
</Python>
May 23 '07 #6

P: n/a
stef a écrit :
thanks Guys for your information,

indeed you're all quit right,
but I think I've not correctly described my problem :-(

I need to have 2 (or more) names, that references the same instance of
an object,
and in assigning a value to the object (or to some property in the object),
I need to do extra activities (like changing some global variables).
Then you want a property (aka computed attribute).
Now if I use a "container type object", without actual using the index
of the container object,
I get things working OK.
But now I have to use a dummy index, if I use the object in assignments,
see program below.
Is there another way, without using the dummy index, to achieve the same
results ?
thanks,
Stef Mientki

<Python>
class cpu_ports(object):
def __init__(self, value=0):
self._d = value
def __setitem__(self, index, value):
print 'vv'
self._d = value
def __getitem__(self, index):
return self._d
def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1[0] = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2[0] = 26 # assign another value through the other name
print name1, name2 # both reference are OK

name2[0] = name1[0] + 13 # use both names at either side of an assignment
print name1, name2 # both references still OK
You can have something working the same way using a property, but that's
how far you'll get - if you hoped to be able to automagically rebind
name2 when rebinding name1, then too bad, because python wont let you do
so. You have to understand that
name = obj
is totally different from
name.attr = obj
or
name[index] = obj

In the first case, this is *really* a binding, and that's one of the few
things that Python won't let you mess with. In the two last cases, it's
in fact a method call - as the use of __[get|set]item__ should make obvious.

here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())

def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1.value = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2.value = 26 # assign another value through the other name
print name1, name2 # both reference are OK

name2.value = name1.value + 13
print name1, name2 # both reference are OK

And that's about as far as you can go (without rewriting Python I mean).
May 23 '07 #7

P: n/a
Bruno Desthuilliers wrote:
stef a écrit :
>thanks Guys for your information,

indeed you're all quit right,
but I think I've not correctly described my problem :-(

I need to have 2 (or more) names, that references the same instance
of an object,
and in assigning a value to the object (or to some property in the
object),
I need to do extra activities (like changing some global variables).

Then you want a property (aka computed attribute).
>Now if I use a "container type object", without actual using the
index of the container object,
I get things working OK.
But now I have to use a dummy index, if I use the object in
assignments, see program below.
Is there another way, without using the dummy index, to achieve the
same results ?
>thanks,
Stef Mientki

<Python>
class cpu_ports(object):
def __init__(self, value=0):
self._d = value
def __setitem__(self, index, value):
print 'vv'
self._d = value
def __getitem__(self, index):
return self._d
def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1[0] = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2[0] = 26 # assign another value through the other
name
print name1, name2 # both reference are OK

name2[0] = name1[0] + 13 # use both names at either side of an
assignment
print name1, name2 # both references still OK

You can have something working the same way using a property, but
that's how far you'll get - if you hoped to be able to automagically
rebind name2 when rebinding name1, then too bad, because python wont
let you do so. You have to understand that
name = obj
is totally different from
name.attr = obj
or
name[index] = obj

In the first case, this is *really* a binding, and that's one of the
few things that Python won't let you mess with. In the two last cases,
it's in fact a method call - as the use of __[get|set]item__ should
make obvious.

here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())

def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1.value = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2.value = 26 # assign another value through the other name
print name1, name2 # both reference are OK

name2.value = name1.value + 13
print name1, name2 # both reference are OK

And that's about as far as you can go (without rewriting Python I mean).
thanks Bruno for your clear explanation,
I was "afraid" that this would be the only solution,
and now I'm sure,
I can implement it in this way (which is not really a problem).

I just found a Python compiler for PICs (Pyastra),
I still have to study it, but it might be a good idea,
to translate JAL to Python, using the exact syntax of Pyastra.

thanks again,
Stef Mientki
May 23 '07 #8

P: n/a
On Wed, 2007-05-23 at 12:55 +0200, stef wrote:
Is there another way, without using the dummy index, to achieve the same
results ?

thanks,
Stef Mientki

<Python>
class cpu_ports(object):
def __init__(self, value=0):
self._d = value
def __setitem__(self, index, value):
print 'vv'
self._d = value
def __getitem__(self, index):
return self._d
def __repr__(self):
return str(self._d)

name1 = cpu_ports() # create an instance
name2 = name1 # refer with a second name to the same instance
print name1, name2 # test ok

name1[0] = 25 # assign a value to the instance
print name1, name2 # both references are OK

name2[0] = 26 # assign another value through the other name
print name1, name2 # both reference are OK

name2[0] = name1[0] + 13 # use both names at either side of an assignment
print name1, name2 # both references still OK
</Python>
An assignment without a dummy index or attribute, i.e. a "plain"
assignment to name1 or name2, will never do what you want, for two
reasons:

1) Assignments modify namespaces, not objects.
2) Assignments can not be overridden.

The reason why the code with dummy indexes works is that those are not
actually namespace-modifying assignments; they are shorthand notations
for __setitem__ method calls. You could achieve the same effect by using
an attribute instead:
>>class A(object): pass
....
>>name1 = A()
name2 = name1
name1.value = 25
print name1.value, name2.value
25 25
>>name2.value = 26
print name1.value, name2.value
26 26
>>name2.value = name1.value + 13
print name1.value, name2.value
39 39

The first statement modifies the namespace by binding the name "name1"
to a newly created instance of class A. The second statement modifies
the namespace by binding the name "name2" to the very same instance.
Until either name1 or name2 are reassigned, the object known as name1 is
now *identical* to the object known as name2. Not equal, not
indistinguishable, but identical. name1 and name2 are two different
names for the same thing.

None of the statements that follow are assignments. They are disguised
__setattr__ method calls on that one object that is known by two names.
Those calls will modify that object (not the namespace), and any changes
made to the object known as name1 are immediately visible in the object
known as name2, because it's the same object.

Hope this helps,

--
Carsten Haese
http://informixdb.sourceforge.net
May 23 '07 #9

P: n/a
Bruno Desthuilliers wrote:
here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())
Wow! I've never seen properties written that way. Kind of takes all the
mess out of what it usually is. Nice. BUT! I don't quite get the
@apply-decorator here. The rest I get and so I gather what it is sort of
kind of supposed to do. I have only found the depricated apply()
function in the docs (which I also don't quite get just by scanning it).
Is it that? If yes: How does it work? If not: What's going on there?

humbly ;)
W
May 23 '07 #10

P: n/a
Perhaps Stef Mientki, you might be interested in copy.copy( ) and
copy.deepcopy( ) ! Please see the info I have put below.

On May 23, 12:44 am, Stef Mientki <S.Mientki-nos...@mailbox.kun.nl>
wrote:
One of the problems is the alias statement, assigning a second name to an object.
I've defined a class IO_port,
and I create an instance of that port with the name port_D

port_D = IO_port('D')
thanks,
Stef Mientki


================================================== ==
The following text is an excerpt from Chapter 12 of book:

How to Think Like a Computer Scientist
Learning with Python
by Allen B. Downey, Jeffrey Elkner and Chris Meyers
[Book available for free download at http://www.thinkpython.com]


=.=.=.=.=.=.=.=.=.=
Chapter 12

Classes and objects

[...]
[...]

12.4 Sameness

The meaning of the word "same" seems perfectly clear until you give it
some thought, and then you realize there is more to it than you
expected.

For example, if you say, "Chris and I have the same car," you mean
that his car and yours are the same make and model, but that they are
two different cars. If you say, "Chris and I have the same mother,"
you mean that his mother and yours are the same person. [...] So the
idea of "sameness" is different depending on the context.

When you talk about objects, there is a similar ambiguity. For
example, if two Points are the same, does that mean they contain the
same data (coordinates) or that they are actually the same object?

To find out if two references refer to the same object, use the ==
operator. For example:
>>p1 = Point()
p1.x = 3
p1.y = 4
p2 = Point()
p2.x = 3
p2.y = 4
p1 == p2
0
Even though p1 and p2 contain the same coordinates, they are not the
same object. If we assign p1 to p2, then the two variables are aliases
of the same object:
>>p2 = p1
p1 == p2
1
This type of equality is called shallow equality because it compares
only the references, not the contents of the objects.

To compare the contents of the objects [use] deep equality... ...
[...]
[...]
12.8 Copying
[...]
[...]
12.9 Glossary

class - A user-defined compound type. A class can also be thought of
as a template for the objects that are instances of it.

instantiate - To create an instance of a class.

instance - An object that belongs to a class.

object - A compound data type that is often used to model a thing or
concept in the real world.

constructor - A method used to create new objects.

attribute - One of the named data items that makes up an instance.

shallow equality - Equality of references, or two references that
point to the same object.

deep equality - Equality of values, or two references that point to
objects that have the same value.

shallow copy - To copy the contents of an object, including any
references to embedded objects; implemented by the copyfunction in the
copy module. Example:
>>b2 = copy.copy(b1)
deep copy - To copy the contents of an object as well as any embedded
objects, and any objects embedded in them, and so on; implemented by
the deepcopy function in the copy module. Example:
>>b2 = copy.deepcopy(b1)

=.=.=.=.=.=.=.=.=.=
The preceding text is an excerpt from Chapter 12 of book:

How to Think Like a Computer Scientist
Learning with Python
by Allen B. Downey, Jeffrey Elkner and Chris Meyers
[Book available for free download at http://www.thinkpython.com]
================================================== ===

Bye from,

Eric Yaeger
Thailand
May 23 '07 #11

P: n/a
Wildemar Wildenburger wrote:
Bruno Desthuilliers wrote:
>here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())
Wow! I've never seen properties written that way. Kind of takes all the
mess out of what it usually is. Nice. BUT! I don't quite get the
@apply-decorator here. The rest I get and so I gather what it is sort of
kind of supposed to do. I have only found the depricated apply()
function in the docs (which I also don't quite get just by scanning it).
Is it that? If yes: How does it work? If not: What's going on there?
It is that very apply.

And apply takes a function as argument + additional arguments, and executes
that function, returning the result of that function-call. It was used
before the

f(*args, **kwargs)

notation was introduced.

Now what we have here is "value" as function, passed as single argument to
apply (because decorators are just callables), which will invoke "value"
with no arguments. The result of that operation is the property-object,
that thus is returned by apply. And in the end gets assigned to the name
value in the cpu_ports-class.

diez
May 23 '07 #12

P: n/a
Wildemar Wildenburger said unto the world upon 05/23/2007 08:43 AM:
Bruno Desthuilliers wrote:
>here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())
Wow! I've never seen properties written that way. Kind of takes all the
mess out of what it usually is. Nice. BUT! I don't quite get the
@apply-decorator here. The rest I get and so I gather what it is sort of
kind of supposed to do. I have only found the depricated apply()
function in the docs (which I also don't quite get just by scanning it).
Is it that? If yes: How does it work? If not: What's going on there?

humbly ;)
W

Hi all,

I had the same sort of question as Wildemar and I set about
investigating as any good pythonista would by typing help(apply) at
the interactive prompt. That produced a help text that started:

Help on built-in function apply in module __builtin__:

But:
>>[x for x in dir('__builtin__') if 'apply' in x]
[]

? If apply is in the __builtin__ module, why doesn't
dir('__builtin__') know about it?

Best to all,

Brian vdB
May 23 '07 #13

P: n/a
Brian van den Broek wrote:
I had the same sort of question as Wildemar and I set about
investigating as any good pythonista would by typing help(apply) at
the interactive prompt. That produced a help text that started:

Help on built-in function apply in module __builtin__:

But:
>>[x for x in dir('__builtin__') if 'apply' in x]
[]

? If apply is in the __builtin__ module, why doesn't
dir('__builtin__') know about it?
The string "__builtin__" doesn't have an apply attribute; but the
__builtin__ module has:
>>import __builtin__
"apply" in dir(__builtin__)
True

Peter
May 23 '07 #14

P: n/a
Peter Otten said unto the world upon 05/23/2007 01:32 PM:
Brian van den Broek wrote:
<snip>
>Help on built-in function apply in module __builtin__:

But:
> >>[x for x in dir('__builtin__') if 'apply' in x]
[]

? If apply is in the __builtin__ module, why doesn't
dir('__builtin__') know about it?

The string "__builtin__" doesn't have an apply attribute; but the
__builtin__ module has:
>>>import __builtin__
"apply" in dir(__builtin__)
True

Peter
Doh!

Thanks Peter.
May 23 '07 #15

P: n/a
hi Bruno,

after study it carefully,
it's much more complex than I thought
(I can't understand it completely, which is of less importance).
Your solution works great,
but I need one little extension,
which I can create, but just at the cost of a lot of code.
Maybe you can give me another hint.
In the first case, this is *really* a binding, and that's one of the few
things that Python won't let you mess with. In the two last cases, it's
in fact a method call - as the use of __[get|set]item__ should make
obvious.

here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())
# I need to read and write the individual bits of the byte object
# so I can create 8 blocks of code like this, one for each bit position
# I use it, like this
# name1 = cpu_ports()
# name1.p5 = True
# or
# name1.p[5] = True

@apply # read / write bit 5
def p5():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())

I can optimize the above code a little bit,
but I've the feeling that I don't need to repeat this code 8 times.

cheers,
Stef Mientki
May 23 '07 #16

P: n/a
Diez B. Roggisch wrote:
It is that very apply.

And apply takes a function as argument + additional arguments, and executes
that function, returning the result of that function-call. It was used
before the

f(*args, **kwargs)

notation was introduced.

Now what we have here is "value" as function, passed as single argument to
apply (because decorators are just callables), which will invoke "value"
with no arguments. The result of that operation is the property-object,
that thus is returned by apply. And in the end gets assigned to the name
value in the cpu_ports-class.
Sooo clever :). But apply is deprecated ... can I do the same thing some
other way?

W
May 23 '07 #17

P: n/a
Wildemar Wildenburger schrieb:
Diez B. Roggisch wrote:
>It is that very apply.

And apply takes a function as argument + additional arguments, and
executes
that function, returning the result of that function-call. It was used
before the
f(*args, **kwargs)

notation was introduced.

Now what we have here is "value" as function, passed as single
argument to
apply (because decorators are just callables), which will invoke "value"
with no arguments. The result of that operation is the property-object,
that thus is returned by apply. And in the end gets assigned to the name
value in the cpu_ports-class.
Sooo clever :). But apply is deprecated ... can I do the same thing some
other way?
Deprecated doesn't mean it's not available. And even if it goes away,
you can simply write it yourself:

def apply(f, *args, **kwargs):
return f(*args, **kwargs)

So, if you want to, you can introduce your own function, e.g.

def makeprop(f):
return f

and then do

class Foo(object):

@makeprop
def bar():
... # the fancy stuff

Diez
May 23 '07 #18

P: n/a
On May 23, 6:22 pm, Wildemar Wildenburger <wilde...@freakmail.de>
wrote:
Diez B. Roggisch wrote:
It is that very apply.
And apply takes a function as argument + additional arguments, and executes
that function, returning the result of that function-call. It was used
before the
f(*args, **kwargs)
notation was introduced.
Now what we have here is "value" as function, passed as single argument to
apply (because decorators are just callables), which will invoke "value"
with no arguments. The result of that operation is the property-object,
that thus is returned by apply. And in the end gets assigned to the name
value in the cpu_ports-class.

Sooo clever :). But apply is deprecated ... can I do the same thing some
other way?

W
Yes; check out the following:

http://aspn.activestate.com/ASPN/Coo.../Recipe/502243
http://aspn.activestate.com/ASPN/Coo.../Recipe/205183
http://aspn.activestate.com/ASPN/Coo.../Recipe/410698

George

May 23 '07 #19

P: n/a
Stef Mientki a écrit :
hi Bruno,

after study it carefully,
it's much more complex than I thought
(I can't understand it completely, which is of less importance).
Your solution works great,
but I need one little extension,
which I can create, but just at the cost of a lot of code.
Maybe you can give me another hint.
>In the first case, this is *really* a binding, and that's one of the few
things that Python won't let you mess with. In the two last cases, it's
in fact a method call - as the use of __[get|set]item__ should make
obvious.

here's an example using a property:

class cpu_ports(object):
def __init__(self, value=0):
self._d = value
@apply
def value():
def fset(self, value):
print 'vv'
self._d = value
def fget(self):
return self._d
return property(**locals())

# I need to read and write the individual bits of the byte object
# so I can create 8 blocks of code like this, one for each bit position
# I use it, like this
# name1 = cpu_ports()
# name1.p5 = True
# or
# name1.p[5] = True

@apply # read / write bit 5
def p5():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())

I can optimize the above code a little bit,
but I've the feeling that I don't need to repeat this code 8 times.
something like that should just work (untested) :

def bit():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :

p1 = bit()
p2 = bit()
p3 = bit()
p4 = bit()
p5 = bit()

But i wonder if you shouldn't use arrays instead :

In [6]:import array

In [7]:help(array)


May 23 '07 #20

P: n/a
Diez B. Roggisch wrote:
Deprecated doesn't mean it's not available.
Is that so? ;)
But it certainly means that some time in the not-too-distant future
"apply" will vanish.

And even if it goes away,
you can simply write it yourself:

def apply(f, *args, **kwargs):
return f(*args, **kwargs)
Do you know that feeling you have, when you've just been shown something
really surprising but utterly simple, that blows you away so much that
for a moment the whole world seems like magic and you feel you are just
a mundane pencilhead? I get that a lot ...
;)
W
May 24 '07 #21

P: n/a
Maric Michaud a écrit :
Stef Mientki a écrit :
(snip)
># I need to read and write the individual bits of the byte object
# so I can create 8 blocks of code like this, one for each bit position
# I use it, like this
# name1 = cpu_ports()
# name1.p5 = True
# or
# name1.p[5] = True

@apply # read / write bit 5
def p5():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())

I can optimize the above code a little bit,
but I've the feeling that I don't need to repeat this code 8 times.

something like that should just work (untested) :

def bit():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :

p1 = bit()
p2 = bit()
p3 = bit()
p4 = bit()
p5 = bit()

As a side note, properties are just an example of objects using the
descriptor protocol. You can build your own descriptors for more
advanced use (think : 'smart' attributes):

http://users.rcn.com/python/download/Descriptor.htm
http://docs.python.org/ref/descriptors.html
May 24 '07 #22

P: n/a
Maric Michaud wrote:
def bit():
def fset(self, value):
index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
index = 5
return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :

p1 = bit()
p2 = bit()
p3 = bit()
p4 = bit()
p5 = bit()
Looks good, but I miss the index :-(
p3 = bit(3)

I tried several of these kind of constructs,
but I can't find a way to pass the index of the bit,
all trials gave Python errors.
This is obvious above my level of knowledge.
So if this isn't possible, I just use the 8 copies ;-)

But i wonder if you shouldn't use arrays instead :

In [6]:import array

In [7]:help(array)
I don't think arrays will help, because most operations will be done on a complete byte.

btw, the first notes about what I'm planning to do, can be seen here:
http://oase.uci.ru.nl/~mientki/data_...imulation.html

thanks,
Stef Mientki
>

May 24 '07 #23

P: n/a
Stef Mientki wrote:
Maric Michaud wrote:
def bit(index):
> def fset(self, value):
> value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
> return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :
p1 = bit(1)
p2 = bit(2)
p3 = bit(3)
p4 = bit(4)
p5 = bit(5)
Looks good, but I miss the index :-(
No more.

Peter
May 24 '07 #24

P: n/a
Peter Otten wrote:
Stef Mientki wrote:
>Maric Michaud wrote:

def bit(index):
>> def fset(self, value):
>> value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
>> return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :

p1 = bit(1)
p2 = bit(2)
p3 = bit(3)
p4 = bit(4)
p5 = bit(5)
>Looks good, but I miss the index :-(

No more.
agreed,
but Python doesn't like it,
and I don't understand why

def bit(index):
def fset(self, value):
#index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
#index = 5
return ( self._d >index ) & 1
return property(**locals())

class cpu_ports(object) :
p1 = bit(1)
p2 = bit(2)
p3 = bit(3)
p4 = bit(4)
p5 = bit(5)
Traceback (most recent call last):
File "<string>", line 209, in run_nodebug
File "D:\data_to_test\rapid_prototyping_board_16F877.py ", line 168, in ?
class cpu_ports(object) :
File "D:\data_to_test\rapid_prototyping_board_16F877.py ", line 169, in cpu_ports
p1 = bit(1)
File "D:\data_to_test\rapid_prototyping_board_16F877.py ", line 166, in bit
return property(**locals())
TypeError: 'index' is an invalid keyword argument for this function

but anyway thanks
Stef
>
Peter
May 24 '07 #25

P: n/a
Stef Mientki wrote:
Peter Otten wrote:
>Stef Mientki wrote:
>>Maric Michaud wrote:

def bit(index):
>>> def fset(self, value):
>>> value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
>>> return ( self._d >index ) & 1
return property(**locals())
class cpu_ports(object) :

p1 = bit(1)
p2 = bit(2)
p3 = bit(3)
p4 = bit(4)
p5 = bit(5)
>>Looks good, but I miss the index :-(

No more.
agreed,
but Python doesn't like it,
and I don't understand why
Because the index is now in the locals() dict. Change the return statement
to fix the error:
def bit(index):
def fset(self, value):
#index = 5
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
#index = 5
return ( self._d >index ) & 1
return property(fget, fset)

Again, I'm confident, again I didn't test.

Peter

May 24 '07 #26

P: n/a
Again, I'm confident, again I didn't test.

I did, ...
.... and unfortunately it still gave errors.

So for the moment I'll just stick to my "lots of code solution",
and I'll try again, when I've some more understanding of these Python "internals".

Anyway,
thank you all for your assistance.

cheers,
Stef Mientki
May 25 '07 #27

P: n/a
Stef Mientki wrote:
>Again, I'm confident, again I didn't test.

I did, ...
... and unfortunately it still gave errors.
Strange.
So for the moment I'll just stick to my "lots of code solution",
and I'll try again, when I've some more understanding of these Python
"internals".
Anyway, here's a self-contained example:

"""
>>p = cpu_ports()
p
cpu_ports(p1=0, p2=0, p3=0, p4=0, p5=0)
>>p.p3 = 1
p
cpu_ports(p1=0, p2=0, p3=1, p4=0, p5=0)
>>p.p4 = 1
p
cpu_ports(p1=0, p2=0, p3=1, p4=1, p5=0)
>>p.p3 = 0
p
cpu_ports(p1=0, p2=0, p3=0, p4=1, p5=0)

"""

def bit(index):
def fset(self, value):
value = ( value & 1L ) << index
mask = ( 1L ) << index
self._d = ( self._d & ~mask ) | value
def fget(self):
return ( self._d >index ) & 1
return property(fget, fset)

class cpu_ports(object) :
def __init__(self):
self._d = 0
def __str__(self):
return "cpu_ports(%s)" % ", ".join(
"%s=%s" % (n, getattr(self, n)) for n in ["p1", "p2", "p3", "p4", "p5"])
__repr__ = __str__
p1 = bit(1)
p2 = bit(2)
p3 = bit(3)
p4 = bit(4)
p5 = bit(5)
if __name__ == "__main__":
import doctest
doctest.testmod()

Peter
May 25 '07 #28

P: n/a
Peter Otten wrote:
Stef Mientki wrote:
>>Again, I'm confident, again I didn't test.
I did, ...
... and unfortunately it still gave errors.

Strange.
indeed ..
>
>So for the moment I'll just stick to my "lots of code solution",
and I'll try again, when I've some more understanding of these Python
"internals".

Anyway, here's a self-contained example:
thanks very much Peter,
this really works like a charm.

Now I've to find out, what I did wrong with your previous suggestions.

cheers,
Stef Mientki
May 25 '07 #29

This discussion thread is closed

Replies have been disabled for this discussion.