[prev in list] [next in list] [prev in thread] [next in thread] 

List:       python-list
Subject:    RE: built-in 'property'
From:       Bob.Cowdery () CGI-Europe ! com
Date:       2004-12-28 21:53:35
Message-ID: 9B40DB5FBF7D2048AD79C2A91F862A51773208 () STEVAPPS05 ! Stevenage ! CGI-Europe ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Thanks to everyone that has helped on this. What I am trying to do is create
a capability based api that I can build to order. This is as far as I get at
the moment.

Each of the first three classes represents some function I can do to a
radio, there would be many of these in practice. The next class is the API.
I figure I have to include all the possible radio function classes in this
as I can't figure out how to make the classes I include per instance. When I
create the API object I pass in a capability array as in the last class. I
use these classes as follows.

>>> import capability as c
>>> import radioapi as r
>>> caps = c.Capability()
>>> cap = caps.getCaps('SDR1000')
>>> cap
['mode', 'freq', 'blanker']
>>> api = r.API(cap)
>>> r.caps
['mode', 'freq', 'blanker']
>>> api.mode
Retrieving mode var "mode"
'lsb'
>>> api.freq
Retrieving freq var "freq"
7.0800000000000001
>>> api.blanker
Retrieving blanker var "blanker"
1
>>> hasattr(api, 'monitor')
0

This is the behaviour I want, each class responds if it is in the capability
array. The user can test attributes with hasattr(klass, 'att') to see if it
is supported. I can create another instance with a different radio and it
will respond accordingly. The problem of course is that in class API, caps
is global so as soon as I create another instance the first starts
responding to the new capability. If I try to make caps per instance I get
into all sorts of trouble with recursion. Does anyone have an idea how to
fix this or is it just impossible to make this work.

Regards
Bob
  
class Mode(object):

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving mode', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating mode' , self.name
        self.val = val
import capability

class Freq(object):

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving freq', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating freq' , self.name
        self.val = val
        
class Blanker(object):

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving blanker', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating blanker' , self.name
        self.val = val      

class API(object):
	
    # create all possible radio classes
    mode=Mode('lsb', 'var "mode"')
    freq=Freq(7.080, 'var "freq"')
    blanker=Blanker(True, 'var "blanker"')
    global caps
    caps = []
    
    def __init__(self, pcaps):
        global caps
        caps = pcaps 

    def __getattribute__(self, key):
        global caps
        if (key in caps) or (key == 'caps'):
            obj = object.__getattribute__(self, key)
            if hasattr(obj, "__get__"):
                return obj.__get__()
            return obj
        else:
            raise AttributeError, "unreadable attribute"

class Capability(object):
    
    m_cap = {
            'SDR1000': ['mode','freq','blanker'],
            'MyRig': ['mode','freq'],
            'YourRig': ['mode', 'blanker']
            }
    
    def getCaps(self, radio):
        return self.m_cap[radio]

*** Confidentiality Notice *** Proprietary/Confidential
Information belonging to CGI Group Inc. and its affiliates
may be contained in this message. If you are not a recipient
indicated or intended in this message (or responsible for
delivery of this message to such person), or you think for
any reason that this message may have been addressed to you
in error, you may not use or copy or deliver this message
to anyone else.  In such case, you should destroy this
message and are asked to notify the sender by reply email.

[Attachment #5 (text/html)]

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2653.12">
<TITLE>RE: built-in 'property'</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=2>Thanks to everyone that has helped on this. What I am trying to do is \
create a capability based api that I can build to order. This is as far as I get at \
the moment.</FONT></P>

<P><FONT SIZE=2>Each of the first three classes represents some function I can do to \
a radio, there would be many of these in practice. The next class is the API. I \
figure I have to include all the possible radio function classes in this as I can't \
figure out how to make the classes I include per instance. When I create the API \
object I pass in a capability array as in the last class. I use these classes as \
follows.</FONT></P>

<P><FONT SIZE=2>&gt;&gt;&gt; import capability as c</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; import radioapi as r</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; caps = c.Capability()</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; cap = caps.getCaps('SDR1000')</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; cap</FONT>
<BR><FONT SIZE=2>['mode', 'freq', 'blanker']</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; api = r.API(cap)</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; r.caps</FONT>
<BR><FONT SIZE=2>['mode', 'freq', 'blanker']</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; api.mode</FONT>
<BR><FONT SIZE=2>Retrieving mode var &quot;mode&quot;</FONT>
<BR><FONT SIZE=2>'lsb'</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; api.freq</FONT>
<BR><FONT SIZE=2>Retrieving freq var &quot;freq&quot;</FONT>
<BR><FONT SIZE=2>7.0800000000000001</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; api.blanker</FONT>
<BR><FONT SIZE=2>Retrieving blanker var &quot;blanker&quot;</FONT>
<BR><FONT SIZE=2>1</FONT>
<BR><FONT SIZE=2>&gt;&gt;&gt; hasattr(api, 'monitor')</FONT>
<BR><FONT SIZE=2>0</FONT>
</P>

<P><FONT SIZE=2>This is the behaviour I want, each class responds if it is in the \
capability array. The user can test attributes with hasattr(klass, 'att') to see if \
it is supported. I can create another instance with a different radio and it will \
respond accordingly. The problem of course is that in class API, caps is global so as \
soon as I create another instance the first starts responding to the new capability. \
If I try to make caps per instance I get into all sorts of trouble with recursion. \
Does anyone have an idea how to fix this or is it just impossible to make this \
work.</FONT></P>

<P><FONT SIZE=2>Regards</FONT>
<BR><FONT SIZE=2>Bob</FONT>
<BR><FONT SIZE=2>&nbsp; </FONT>
<BR><FONT SIZE=2>class Mode(object):</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __init__(self, initval=None, \
name='var'):</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.val = initval</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.name = name</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __get__(self, obj, objtype):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Retrieving mode', \
self.name</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return \
self.val</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __set__(self, obj, val):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Updating mode' , \
self.name</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.val \
= val</FONT> <BR><FONT SIZE=2>import capability</FONT>
</P>

<P><FONT SIZE=2>class Freq(object):</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __init__(self, initval=None, \
name='var'):</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.val = initval</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.name = name</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __get__(self, obj, objtype):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Retrieving freq', \
self.name</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return \
self.val</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __set__(self, obj, val):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Updating freq' , \
self.name</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.val \
= val</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>class Blanker(object):</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __init__(self, initval=None, \
name='var'):</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.val = initval</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.name = name</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __get__(self, obj, objtype):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Retrieving \
blanker', self.name</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.val</FONT> </P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __set__(self, obj, val):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'Updating blanker' \
, self.name</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
self.val = val&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT> </P>

<P><FONT SIZE=2>class API(object):</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # create all possible radio classes</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; mode=Mode('lsb', 'var &quot;mode&quot;')</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; freq=Freq(7.080, 'var &quot;freq&quot;')</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; blanker=Blanker(True, 'var \
&quot;blanker&quot;')</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; global caps</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; caps = []</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __init__(self, pcaps):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; global caps</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; caps = pcaps </FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def __getattribute__(self, key):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; global caps</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (key in caps) or (key \
== 'caps'):</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj = \
object.__getattribute__(self, key)</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if \
hasattr(obj, &quot;__get__&quot;):</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
return obj.__get__()</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return \
obj</FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
raise AttributeError, &quot;unreadable attribute&quot;</FONT> </P>

<P><FONT SIZE=2>class Capability(object):</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; m_cap = {</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
'SDR1000': ['mode','freq','blanker'],</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'MyRig': \
['mode','freq'],</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'YourRig': \
['mode', 'blanker']</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT> \
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; </FONT> <BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; def \
getCaps(self, radio):</FONT> <BR><FONT \
SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.m_cap[radio]</FONT> \
</P>


<P><STRONG>*** Confidentiality Notice ***</STRONG> 
Proprietary/Confidential<BR>Information belonging to CGI Group Inc. and its 
affiliates<BR>may be contained in this message. If you are not a 
recipient<BR>indicated or intended in this message (or responsible 
for<BR>delivery of this message to such person), or you think for<BR>any reason 
that this message may have been addressed to you<BR>in error, you may not use or 
copy or deliver this message<BR>to anyone else.&nbsp; In such case, you should 
destroy this<BR>message and are asked to notify the sender by reply 
email.</P>
</BODY>
</HTML>



-- 
http://mail.python.org/mailman/listinfo/python-list

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic