473,668 Members | 2,583 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Metaprogramming Example


Hi,

Thanks for the help a couple of days ago. I completed what I was
doing and wrote a summary which I've posted at http://acooke.org/cute/PythonMeta0.html
(it's kind of long to post here). I hope it might be useful to
someone else - it's complete code for a simple metaprogramming task
that uses metaclasses and descriptors.

I'd also appreciate further feedback if I've done anything stupid or
if there's some interesting approach I've missed that might work
better.

Thanks again,
Andrew
Jun 27 '08 #1
9 1627
On 17 avr, 04:27, andrew cooke <and...@acooke. orgwrote:
Hi,

Thanks for the help a couple of days ago. I completed what I was
doing and wrote a summary which I've posted athttp://acooke.org/cute/PythonMeta0.htm l
(it's kind of long to post here). I hope it might be useful to
someone else - it's complete code for a simple metaprogramming task
that uses metaclasses and descriptors.

I'd also appreciate further feedback if I've done anything stupid or
if there's some interesting approach I've missed that might work
better.
1/ Not about metaprogramming , but ORMs. You write:
"""
I could use an existing ORM package, but my experience with
them hasn't been that positive (in particular, I find SQL to be very
useful and want to use it more than is normally possible with standard
ORM).
"""

Makes me wonder if you really took a close-enough look at
SQLAlchemy... (please ignore this if you did)
2/ about your code:

if (self.ignore_id entical is False or
new_value is not obj._auto_write _dict[self.name]):

Take care, 'is' is the identity test operator, not the equality test
operator. I think you *really* want the equality operator here. If you
don't understand why, here's a sample run that's worth a longer
explanation:
>>a = "it's wrong"
b = "it's wrong"
a is b
False
>>a == b
True
>>c = 99999
d = 99999
c is d
False
>>c == d
True
>>0 is False
False
>>0 == False
True
>>>
Also, the parens are not needed, and boolean tests don't need to be
that explicit (ie, you don't necessarily need to test a boolean
expression against True or False). And, last point, double-negations
can be harder to understand.

May I suggest:

if not (self.ignore_id entical and new_value ==
obj._auto_write _dict[self.name]):
3/ code again:

attr = getattr(obj.__c lass__,
"%s%s" % (self.prefix, self.name), None)
obj._auto_write _dict[self.name] = attr(obj, new_value)

Three points here:
- build the setter name once and "cache" it. It'll make your code more
readable (and save a couple cycles)

def __init__(self, name, ignore_identica l=True, prefix='_set_') :
self.name = name
self.ignore_ide ntical = ignore_identica l
self.prefix = prefix
self.settername = "%s%s" % (self.prefix, self.name)

then use self.settername in __set__

- retrieving the setter on the object (instead of it's class) would be
more pythonic, and way simpler to read.

- None is not callable, so you code will crash if the object doesn't
define a setter. You can either test the return value of getattr
against None, put a try/except around the call, or use an identity
function as default value for getattr (which is what I'd do here)

Fix:

setter = getattr(obj, self.settername , lambda x : x)
obj._auto_write _dict[self.name] = setter(new_valu e)

About the article itself, I'd say it makes a good introduction to a
common metaprogramming pattern, but you'd have to get the opinion of
someone that has no experience with these topics. Ho, and yes : one
day, you'll get why it's such a good thing to unite functions and
methods !-)

My 2 cents
Jun 27 '08 #2
On Apr 17, 7:12 am, "bruno.desthuil li...@gmail.com "
<bruno.desthuil li...@gmail.com wrote:
[...]

Thanks very much!

These are useful pointers. I'll update my code accordingly.

At one point you pointed out I didn't need parentheses and I agree - I
was using them to avoid having a line continuation backslash (I think
I read to do that in a style guide recently).

One other question. I had "foo is False" and you said I need
equality, which is a good point. However, in any other language "not
foo" would be preferable. I was surprised you didn't suggest that
(and I'm unsure now why I didn't write it that way myself). Is there
some common Python standard that prefers "foo == False" to "not foo"?

Thanks,
Andrew

PS Is there anywhere that explains why Decorators (in the context of
functions/methods) are so good? I've read lots of things saying they
are good, but no real justification of why. To me it looks more like
"re-arranging deck chairs on the Titanic" - you're just moving where
the hack happens from one place to another. Is the point that now the
hack is more visible and hence modifiable?
Jun 27 '08 #3
On Apr 17, 7:25*am, andrew cooke <and...@acooke. orgwrote:
On Apr 17, 7:12 am, "bruno.desthuil li...@gmail.com "<bruno.desthui lli...@gmail.co mwrote:

One other question. *I had "foo is False" and you said I need
equality, which is a good point. *However, in any other language "not
foo" would be preferable. *I was surprised you didn't suggest that
(and I'm unsure now why I didn't write it that way myself). *Is there
some common Python standard that prefers "foo == False" to "not foo"?
In addition to the problematic "foo is False" test, Bruno was also
saying that assertions of True tend to be more readable than negated
assertions of False.

In your original, you were testing for not P or not Q, Bruno recoded
this to the equivalent not(P and Q). That is, the direct way to
change the 'is' identity testing to equality testing would have been:

if (not self.ignore_ide ntical or
new_value != obj._auto_write _dict[self.name]):

But Bruno further changed this to:

if not (self.ignore_id entical and
new_value == obj._auto_write _dict[self.name]):
-- Paul
Jun 27 '08 #4
On 17 avr, 14:25, andrew cooke <and...@acooke. orgwrote:
On Apr 17, 7:12 am, "bruno.desthuil li...@gmail.com "<bruno.desthui lli...@gmail.co mwrote:

[...]

Thanks very much!

These are useful pointers. I'll update my code accordingly.

At one point you pointed out I didn't need parentheses and I agree - I
was using them to avoid having a line continuation backslash (I think
I read to do that in a style guide recently).
Ok. I personnaly prefer \ continuations, but that's another
troll^M^discuss ion !-)
One other question. I had "foo is False" and you said I need
equality, which is a good point. However, in any other language "not
foo" would be preferable.
And it's indeed the case in Python.
I was surprised you didn't suggest that
I did - even if somewhat implicitly -, as Paul brillantly explained.
(and I'm unsure now why I didn't write it that way myself). Is there
some common Python standard that prefers "foo == False" to "not foo"?
Definitively not.

FWIW, True and False are later additions to Python, which has a much
more generic concept of what's true or false (notice the lowercase) in
the context of a boolean expression, that is:
- False, None, numeric zero are false
- an object that has a __nonzero__ method has the truth value of the
result of calling this method
- a "sizeable" object (one which defines a __len__ method) is true if
len(obj) 0, else it's false (which implies that empty dicts, lists,
tuples and strings are false)
- anything else is true

(please someone correct me if I forgot something here).

>
PS Is there anywhere that explains why Decorators (in the context of
functions/methods) are so good? I've read lots of things saying they
are good, but no real justification of why. To me it looks more like
"re-arranging deck chairs on the Titanic" - you're just moving where
the hack happens from one place to another. Is the point that now the
hack is more visible and hence modifiable?
I wouldn't call function decorators "a hack" - it's just a pretty
common use of HOFs. Now wrt/ the @decorator syntax: yes, you're plain
right, the GoodThing(tm) is that it makes the use of the HOF clearly
visible at the top of the function definition so you just can't miss
it.

Jun 27 '08 #5
bruno:
Ho, and yes : one day, you'll get why it's such a good thing to unite
functions and methods !-)
me:
PS Is there anywhere that explains why Decorators (in the context of
functions/methods) are so good? I've read lots of things saying they
are good, but no real justification of why.
in the text above i wrote "Decorators " rather than "Descriptor s". it
was in response to bruno's comment, also above. sorry for the
confusion.
also, sorry for the inflammatory language - by referring to the
titanic
i didn't mean that python was a disaster, rather that the "iceberg" is
still there (i am not 100% sure what the iceberg is, but it's
something
to do with making namespaces explicit in some places and not others).

anyway, it was only a small point. thanks for all the replies.
didn't
respond earlier as i was at work. now i can go back and polish that
code...

andrew
Jun 27 '08 #6
andrew cooke a écrit :
bruno:
>Ho, and yes : one day, you'll get why it's such a good thing to unite
functions and methods !-)

me:
>PS Is there anywhere that explains why Decorators (in the context of
functions/methods) are so good? I've read lots of things saying they
are good, but no real justification of why.

in the text above i wrote "Decorators " rather than "Descriptor s". it
was in response to bruno's comment, also above. sorry for the
confusion.
Ho, you meant Descriptors ?

Well, a first point is that the support for methods is built on a
combination of two "general purpose" constructs - callable objects and
the descriptor protocol - instead of being a special-case construct by
itself. IOW, this is build *with* Python itself, instead of being built
*into* Python.

Practically, this means that (amongst other niceties) :
- you can define functions outside classes and use them as instance or
class methods
- you can add/replaces methods dynamically on a per-class or
per-instance basis
- you can access the function object of a method and use it as a function
- you can define your own callable types, that - if you implement the
appropriate support for the descriptor protocol - will be usable as
methods too

also, sorry for the inflammatory language
Which one ???
by referring to the titanic
i didn't mean that python was a disaster, rather that the "iceberg" is
still there (i am not 100% sure what the iceberg is, but it's
something
to do with making namespaces explicit in some places and not others).
I guess you're thinking of the self argument, declared in the function's
signature but not "explicitly passed" when calling the method ?

If so, the fact is you *do* pass it explicitly - by calling the function
*as a method of an objet*. Given the following definitions:

def func(obj, data):
print "obj : %s - data : %s" % (obj, data)

class Foo(object):
meth = func

f = Foo()

What the difference between:

func(f, 42)

and

f.meth(42)

In both cases, f is directly and explicitly involved as one of the
"targets" of the call.

My 2 cents...
Jun 27 '08 #7
On Apr 18, 4:48 am, Bruno Desthuilliers <bruno.
42.desthuilli.. .@websiteburo.i nvalidwrote:
[...]
Practically, this means that (amongst other niceties) :
- you can define functions outside classes and use them as instance or
class methods
- you can add/replaces methods dynamically on a per-class or
per-instance basis
- you can access the function object of a method and use it as a function
- you can define your own callable types, that - if you implement the
appropriate support for the descriptor protocol - will be usable as
methods too
ok, that's convincing (i had thought the majority of these were
already
possible, albeit with some kind of hard-coded "magic" behind the
scenes).

[...]
by referring to the titanic
i didn't mean that python was a disaster, rather that the "iceberg" is
still there (i am not 100% sure what the iceberg is, but it's
something
to do with making namespaces explicit in some places and not others).

I guess you're thinking of the self argument, declared in the function's
signature but not "explicitly passed" when calling the method ?
not really. more to do with when namespaces (i am not sure i have the
right term - the dictionary that provides the mapping from name to
object)
are explicit or implicit. for example, python has closures (implicit
lookup) and "self" (explicit lookup).

but as i said, i don't have a clear argument - something just feels
"odd".
at the same time, i know that language design is a practical business
and so this is probably not important.

finally, thank you for pointing me to sql alchemy (i think it was
you?).
it really is excellent.

andrew
Jun 27 '08 #8
On 17 Apr., 14:25, andrew cooke <and...@acooke. orgwrote:
PS Is there anywhere that explains why Decorators (in the context of
functions/methods) are so good?
We had kind of an inverse discussion a while ago when someone asked
about the fate of aspect oriented programming (AOP) in Python. My
answer was that technically "aspect weaving" using code generators is
dead in application programming [1] and decorators are handy,
lightweight, local and controllable while serving very similar
purposes.

[1] There are occasions where source code weaving might still has its
place. Profiling for example or code coverage. Just examine this
interesting blog article:

http://nedbatchelder.com/blog/200804...e_tracing.html

and the subsequent discussion.
Jun 27 '08 #9
On 19 avr, 16:34, andrew cooke <and...@acooke. orgwrote:
On Apr 18, 4:48 am, Bruno Desthuilliers <bruno.42.desth uilli...@websit eburo.invalidwr ote:

[...]
Practically, this means that (amongst other niceties) :
- you can define functions outside classes and use them as instance or
class methods
- you can add/replaces methods dynamically on a per-class or
per-instance basis
- you can access the function object of a method and use it as a function
- you can define your own callable types, that - if you implement the
appropriate support for the descriptor protocol - will be usable as
methods too

ok, that's convincing (i had thought the majority of these were
already
possible, albeit with some kind of hard-coded "magic" behind the
scenes).
Yep, the whole point is that it's not that hard-coded anymore. Python
exposes most of it's inner mechanisms, so that you can taylor quite a
lot of things to your needs. This is quite useful for writing clean
frameworks needing very few boilerplate in the user code.
[...]
by referring to the titanic
i didn't mean that python was a disaster, rather that the "iceberg" is
still there (i am not 100% sure what the iceberg is, but it's
something
to do with making namespaces explicit in some places and not others).
I guess you're thinking of the self argument, declared in the function's
signature but not "explicitly passed" when calling the method ?

not really. more to do with when namespaces (i am not sure i have the
right term - the dictionary that provides the mapping from name to
object)
are explicit or implicit. for example, python has closures (implicit
lookup) and "self" (explicit lookup).

but as i said, i don't have a clear argument - something just feels
"odd".
at the same time, i know that language design is a practical business
and so this is probably not important.
The fact is that everything you do with closures can be done with
objects. OTHO, there are quite a lot of cases where defining a
specific class would be just way too heavy, and a closure is much more
lightweight. So yes, it's a matter of "practicali ty beats purity".
While trying to remain as clean as possible, Python is definitively a
practical language.
finally, thank you for pointing me to sql alchemy (i think it was
you?).
Seems so.
it really is excellent.
Indeed !-)
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2152
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the code)? It's not a perfect analogy, but it seems to be a reasonable statement...
3
1686
by: David Abrahams | last post by:
Readers of this newsgroup might like to know that Aleksey Gurtovoy and I have written a book titled _C++ Template Metaprogramming: Concepts, Tools and Techniques from Boost and Beyond_. The book has recently entered copyediting, and will be published by Addison Wesley in this Fall. If you're interested you can peruse some sample chapters at http://boost-consulting.com/mplbook. -- Dave Abrahams Boost Consulting
21
2094
by: Protoman | last post by:
I've been looking at template metaprogramming. It seems really cool, make the compiler do most of the work. I have very simple program that uses TMP,it calculates the square of a number, but it doesn't seem to work. Here it is: #include <iostream> #include <cstdlib> using namespace std; template<int n>
9
3418
by: PengYu.UT | last post by:
Hi, I have the code below this email. I want to replace the last 4 lines with a Metaprogramming loop to get something like the following (I don't know the syntax). Is it possible? for type in {left_tag, right_tag, down_tag, up_tag) { fun(type()); }
7
3489
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template metaprogramming is supported in C# (.NET)? For reference I found it: http://en.wikipedia.org/wiki/Template_metaprogramming. Thanks to all.
1
2379
by: Ted | last post by:
I have cross posted this to comp.lang.c++ and to sci.math.num- analysis in the belief that the topic is of interest to some in both groups. I am building my toolkit, in support of my efforts in producing high performance C++ code; code that is provably correct. The issue here is orthogonal to the question of expression templates, which at present seem to me to be relatively simple.
4
1859
by: suman.nandan | last post by:
Hi C++ Experts ! I have a little weird requirement. I have a base class, say B and lots of classes D1 .. Dn publicly derived from it. Over the course of development the number of derived classes may increase. I want that before the execution of one of my particular code, I should have a list of pointers to all the derived classes, say std::list<B*ptrList; // contains 'n' elements which are pointers to D1 .. Dn.
16
1608
by: Wilson | last post by:
Hi all, I have an interesting problem that I'm hoping can be solved with metaprogramming, but I don't know how far Python supports code generation (and I don't know if I'm taking the correct approach either... hence why I'm asking on this group): I'd like to write a program that writes/manipulates a statemachine. My idea was that I would define states in a .py file along with their transitions and other metadata. I could then write a...
12
3338
by: nooneinparticular314159 | last post by:
Hello. If I declare the following: template<int a, int b, int SomeArray> class DoSomething{ public: .. .. ..
0
8462
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8381
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8583
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8656
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6209
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5681
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4205
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2023
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1786
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.