I'm trying to dynamically generate class methods which have access to
some state passed in at creation time. (Basically as a workaround to
twisted's trial not having a way to dynamically add stuff. Plain
unittest seems to have TestSuite, but the trial runner doesn't know
about it.)
My first attempt might better illustrate this -
class Foo:
def generalized(self, ctx):
print 'my ctx is %r' % ctx
for i in ['a','b','c']:
setattr(Foo, i, lambda self: self.generalized(i))
foo = Foo()
foo.a()
foo.b()
foo.c()
but this prints "my ctx is c" three times; I'd hoped for a, b, c, of
course. After reading
<http://mail.python.org/pipermail/python-list/2004-July/229478.html>, I
think I understand why this is - "i" doesn't actually get added to each
new function's context; they just reference the global one. Even if I
do this:
def builder():
for i in ['a','b','c']:
setattr(Foo, i, lambda self: self.generalized(i))
builder()
they'll just keep a reference to the context that was made on entry to
builder() and share it, so the modifications builder() makes to i are
reflected in all three functions.
Okay, take two. I tried this:
try:
from functional import partial
except ImportError:
...partial pasted from PEP 309...
for i in ['a','b','c']:
setattr(Foo, i, partial(Foo.generalized, ctx=i))
but when I try to call foo.a(), I get this error:
Traceback (most recent call last):
File "./foo.py", line 35, in ?
foo.a()
File "./foo.py", line 25, in __call__
return self.fn(*(self.args + args), **d)
TypeError: unbound method generalized() must be called with Foo
instance as first argument (got nothing instead)
If I add a debug print to partial.__call__,
print 'partial.__call__(args=%r, kw=%r, self.kw=%r)' \
% (args, kw, self.kw)
I see:
partial.__call__(args=(), kw={}, self.kw={'ctx': 'a'})
I'd first expected foo.a() to be equivalent to Foo.a(self), but instead
it's like Foo.a(). There must be magic that does the equivalent of
class Foo:
def __init__(self):
a = partial(a, self)
for real Python functions and not for my partial object.
With this __init__ magic, I guess I have something that works. I have
to apply the partial twice, though - if I do everything in the
__init__, my new functions won't exist by the time trial's
introspection kicks in, so they'll never get called. My ugly hack has
gotten even uglier.
Does anyone know of a better way to do this?
Thanks,
Scott 3 1481
On 2006-08-17, Scott Lamb <sr****@gmail.comwrote:
I'm trying to dynamically generate class methods which have access to
some state passed in at creation time. (Basically as a workaround to
twisted's trial not having a way to dynamically add stuff. Plain
unittest seems to have TestSuite, but the trial runner doesn't know
about it.)
My first attempt might better illustrate this -
class Foo:
def generalized(self, ctx):
print 'my ctx is %r' % ctx
for i in ['a','b','c']:
setattr(Foo, i, lambda self: self.generalized(i))
foo = Foo()
foo.a()
foo.b()
foo.c()
but this prints "my ctx is c" three times; I'd hoped for a, b, c, of
course. After reading <http://mail.python.org/pipermail/python-list/2004-July/229478.html>, I
think I understand why this is - "i" doesn't actually get added to each
new function's context; they just reference the global one. Even if I
do this:
Try this instead as the for loop
for i in ['a','b','c']:
setattr(Foo, i, lambda self, a=i: self.generalized(a))
--
Antoon Pardon
Scott Lamb wrote:
I'm trying to dynamically generate class methods which have access to
some state passed in at creation time. (Basically as a workaround to
twisted's trial not having a way to dynamically add stuff. Plain
unittest seems to have TestSuite, but the trial runner doesn't know
about it.)
My first attempt might better illustrate this -
class Foo:
def generalized(self, ctx):
print 'my ctx is %r' % ctx
for i in ['a','b','c']:
setattr(Foo, i, lambda self: self.generalized(i))
foo = Foo()
foo.a()
foo.b()
foo.c()
but this prints "my ctx is c" three times; I'd hoped for a, b, c, of
course.
def build(j):
setattr(Foo, j, lambda self: self.generalized(j))
for i in ["a","b","c"]:
build(i)
Each call of the the build function creates its own cell "j" that the
lambda references.
Carl Banks
Thanks, Antoon and Carl. Just tried your solutions - both work and are
much cleaner than mine. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Holger Türk |
last post by:
Hello,
a common pattern to write curried functions (i.e. without the
need for a special partial application syntax, like in PEP 309)
is like in this example:
def functionLock (lk):
def...
|
by: Neil Zanella |
last post by:
Hello,
I would like to know whether it is possible to define static class methods
and data members in Python (similar to the way it can be done in C++ or Java).
These do not seem to be mentioned...
|
by: John M. Gabriele |
last post by:
I've done some C++ and Java in the past, and have recently learned
a fair amount of Python. One thing I still really don't get though
is the difference between class methods and instance methods. I...
|
by: svend |
last post by:
Hey there,
I was thinking about some curried functions in JavaScript, and I made
this:
<script>
function add(a, b, c) {
if (arguments.length == 1) {
return function (d,e) {return a + d + e}...
|
by: WXS |
last post by:
Vote for this idea if you like it here:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=5fee280d-085e-4fe2-af35-254fbbe96ee9...
| |
by: emin.shopper |
last post by:
I had a need recently to check if my subclasses properly implemented
the desired interface and wished that I could use something like an
abstract base class in python. After reading up on metaclass...
|
by: Steve Richter |
last post by:
in a generic class, can I code the class so that I can call a static
method of the generic class T?
In the ConvertFrom method of the generic TypeConvert class I want to
write, I have a call to...
|
by: Sanders Kaufman |
last post by:
I'm wondering if I'm doing this right, as far as using another class
object as a PHP class property.
class my_baseclass {
var $Database;
var $ErrorMessage;
var $TableName;
var $RecordSet;...
|
by: fgh.vbn.rty |
last post by:
Hi,
I'm not sure if i'm asking the question correctly but anyway here it
is.
Say I have 3 classes - class A, class B, class R.
1) A and B are the building blocks and R is like a repository...
|
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,...
|
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...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
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...
|
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...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
| |