Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #19115
| Path | csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail |
|---|---|
| Return-Path | <huayanghao@gmail.com> |
| X-Original-To | python-list@python.org |
| Delivered-To | python-list@mail.python.org |
| X-Spam-Status | OK 0.000 |
| X-Spam-Evidence | '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'python.': 0.04; 'parameter': 0.05; 'suppose': 0.05; 'subject:Python': 0.05; 'python': 0.08; 'attribute.': 0.09; 'bits.': 0.09; 'descriptor': 0.09; 'descriptors': 0.09; 'first:': 0.09; 'googled': 0.09; 'properly.': 0.09; 'def': 0.13; 'received:209.85.210.174': 0.13; 'received:mail-iy0-f174.google.com': 0.13; 'protocol': 0.15; '"register"': 0.16; '107': 0.16; '117': 0.16; 'attribute,': 0.16; 'instantiated': 0.16; 'metaclass': 0.16; 'name)': 0.16; 'name):': 0.16; 'instance': 0.18; 'seems': 0.19; '(or': 0.22; "doesn't": 0.22; 'here?': 0.23; 'values.': 0.23; 'consist': 0.24; 'skip:_ 20': 0.26; 'all,': 0.27; "i'm": 0.27; 'bit': 0.28; 'message- id:@mail.gmail.com': 0.28; 'pass': 0.28; 'class': 0.29; 'invoke': 0.30; 'pattern': 0.30; 'protocols': 0.30; 'value)': 0.30; 'does': 0.32; 'that,': 0.32; 'thanks': 0.32; 'to:addr:python-list': 0.33; 'there': 0.33; 'field,': 0.34; 'calling': 0.34; 'smart': 0.34; 'try:': 0.34; 'here,': 0.34; 'issue': 0.35; 'facing': 0.36; 'run': 0.37; 'reference': 0.37; 'but': 0.37; 'received:google.com': 0.37; 'skip:_ 10': 0.37; 'enough': 0.37; 'some': 0.38; 'received:209.85': 0.38; 'skip:o 20': 0.38; 'sometimes': 0.38; 'should': 0.38; 'e.g.': 0.38; 'why': 0.39; 'except': 0.39; 'called': 0.39; 'received:209': 0.39; 'or,': 0.39; 'to:addr:python.org': 0.40; 'type': 0.60; 'design': 0.61; 'below': 0.63; 'share': 0.66; 'divided': 0.73; 'charm': 0.84; 'value):': 0.84; '111': 0.91; 'fields,': 0.91 |
| DKIM-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; bh=TO0u/x0h6xg0ej9iCRe29mLQFMSznivwl5Obh9CLTnY=; b=iOjspCYr72BhFiHneE8ahFJGeSP4IYWhEevSirxQOc36VVXJVwBXEoYK+o/H78yRAh WooYKQDc9dxYesNQVQNf8Gza9nXR3wbha+YnZoMRYN7tPbjU/sBF6KFjfj3V66aho3pC 6phcFzeFEbdx10P08375s5E1CrrozF1OZk9sY= |
| MIME-Version | 1.0 |
| Date | Thu, 19 Jan 2012 13:55:21 +0800 |
| Subject | Python Descriptor as Instance Attribute |
| From | Hua Yanghao <huayanghao@gmail.com> |
| To | python-list@python.org |
| Content-Type | text/plain; charset=UTF-8 |
| X-BeenThere | python-list@python.org |
| X-Mailman-Version | 2.1.12 |
| Precedence | list |
| List-Id | General discussion list for the Python programming language <python-list.python.org> |
| List-Unsubscribe | <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe> |
| List-Archive | <http://mail.python.org/pipermail/python-list> |
| List-Post | <mailto:python-list@python.org> |
| List-Help | <mailto:python-list-request@python.org?subject=help> |
| List-Subscribe | <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.4851.1326952524.27778.python-list@python.org> (permalink) |
| Lines | 65 |
| NNTP-Posting-Host | 2001:888:2000:d::a6 |
| X-Trace | 1326952524 news.xs4all.nl 6976 [2001:888:2000:d::a6]:42932 |
| X-Complaints-To | abuse@xs4all.nl |
| Xref | x330-a1.tempe.blueboxinc.net comp.lang.python:19115 |
Show key headers only | View raw
Hi all,
Currently descriptors only work as class attribute,
and doesn't work as a descriptor when it is an instance attribute.
e.g. if we have descriptor class DescriptorTest,
class Dummy(object):
d = DescriptorTest()
class Dummy2(object):
def __init__(self):
self.d = DescriptorTest()
The instance of Dummy2 does not invoke the descriptor protocols on "d".
Whereas Dummy() instances all share the same descriptor "d".
Yes I know d.__get__() have an "instance" parameter which can be used
to store per-instance values, but sometimes it is just not enough (or it is that
I do not know a better approach exists).
Suppose the below scenario, I want to model a "Register". A register is consist
of some fields, which have different number of bits.
e.g. a 32 bit register divided into 3 field, bit[0] to bit[7] is
called M, bit[8] to bit[15]
is called N, and bit[16] to bit[31] is called Z.
I want to model a register that, when instantiated as "reg", reg.M/N/Z
can directly
reference each field, calling a descriptor protocol to verify and
return the values.
Yes, I know I can use metaclass to create a different class for
different registers,
but that's not seems to be a very smart approach here, as I want all
register instances
be of type "Register". But the default python protocol will not run
descriptor protocols
if a descriptor is an instance attribute. I'm sure I should not be the
only one that facing
this issue and I googled around and found a solution to redefine the
__setattr__ and
__getattribute__ to look up the descriptor protocols first:
107 def __getattribute__(self, name):
108 value = object.__getattribute__(self, name)
109 if hasattr(value, '__get__'):
110 value = value.__get__(self, self.__class__)
111 return value
112
113 def __setattr__(self, name, value):
114 try:
115 obj = object.__getattribute__(self, name)
116 except AttributeError:
117 pass
118 else:
119 if hasattr(obj, '__set__'):
120 return obj.__set__(self, value)
121 return object.__setattr__(self, name, value)
This works like a charm and each instance of "Register" now invoke the
descriptors properly.
I just do not understand, why such behavior is not a default in python.
Or, is there a better design pattern here?
Thanks & Best Regards,
Hua Yanghao
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Python Descriptor as Instance Attribute Hua Yanghao <huayanghao@gmail.com> - 2012-01-19 13:55 +0800
csiph-web