473,378 Members | 1,067 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

dynamically generated runtime methods & reflection

Hi all,

First, apologies if anyone gets this twice, but it took me quite a
while to figure out that Python.org is evidently rejecting all mail
from my mail server because I don't have reverse DNS configured.
Anyway:

I'm not even sure how to phrase this question properly or the right
terminology on this so bear with me. What I'm looking to find out is

a) is there a functionality in Python where I can call a method I have
not defined ahead of time, and based on the method name, change the
functionality of the method at runtime?

b) if not, what is the "Pythonic" approach to the problem outlined
below? Any recommendations on how to approach the problem differently
are welcome.

I've googled and read my Python reference pretty extensively and I've
found some hints but nothing that really answered my questions, so
here I am :-) I did figure out that you can overload __getattr__ in
a clas to define a new method at runtime, but I got stuck when I
couldn't figure out how to have a method know what name it was
originally called with. That's the basic question, see below for the
context I'm asking the question in and *why* I want to do the above
:-)

-----

The software product I work on has a socket-based API that can be
accessed directly via telnet & manually typing commands, or by a set
of Perl modules that wrap the socket functionality. I am looking to
write a set of Python modules that match the same functionality.
Basically you can telnet to a port and type something like

item.list "param1=value1", "param2=value2"

And it will return the results (if any) to you in a given format along
with a response code, e.g. 200 OK or 400 ERROR. The Perl modules just
wrap this so that instead of the above, you can do something like
this:

$MySocketServer = new SocketServer(Host=>'127.0.0.'1, Port=>'9999');

if (! $MySocketServer->ListItem(itemName=>$item_name)) {
print "failed to retrieve list";
print "reason: " . $MySocketServer->GetErrorMsg();
exit;
}
The ListItem() method handles the work of communicating across the
socket, waiting for the response, and determine the success/failure
based on the return code. The part where it gets interesting is that
our Perl modules don't actually have a ListItem() method. Instead,
there is a generalized "_api_func()" method that looks at the name of
the method you called (using Autoload I believe, for any Perlheads out
there), and bases the action taken on the name.

In the example above, for instance, it sees that you called
ListItem(), so it transforms that to item.list and makes the
parameters of the method the parameters that are passed to item.list
via the socket server. Then it takes the response back from the socket
to determine the function return code. If there are any results such
as a list of items, they are then able to be accessed through a
reference to a hash of the results, and there is a GetResultRef
accessor function. In essence, our Perl modules are an incredibly
lightweight, simplistic wrapper for the socket-based API, and almost
all of the work is offloaded to the API implementation server-side.

I welcome any suggestions, feedback, sample code, documentation,
whitepapers etc. The only thing I don't want to have to do is go and
define a separate method for every single one of the possible
permutations of socket commands if I can avoid it!

-----

Thanks in advance,

-Jay
Jun 14 '07 #1
7 1280
Jay Loden wrote:
Hi all,

First, apologies if anyone gets this twice, but it took me quite a
while to figure out that Python.org is evidently rejecting all mail
from my mail server because I don't have reverse DNS configured.
Anyway:

I'm not even sure how to phrase this question properly or the right
terminology on this so bear with me. What I'm looking to find out is

a) is there a functionality in Python where I can call a method I have
not defined ahead of time, and based on the method name, change the
functionality of the method at runtime?
Yes. Implement a __getattr__ method on your class (which you mention).
b) if not, what is the "Pythonic" approach to the problem outlined
below? Any recommendations on how to approach the problem differently
are welcome.

I've googled and read my Python reference pretty extensively and I've
found some hints but nothing that really answered my questions, so
here I am :-) I did figure out that you can overload __getattr__ in
a clas to define a new method at runtime, but I got stuck when I
couldn't figure out how to have a method know what name it was
originally called with. That's the basic question, see below for the
context I'm asking the question in and *why* I want to do the above
:-)
Ahh, so you want to pass the method name to the method that you are
returning to be called. No problem.
>>import functools

class foo:
.... def __getattr__(self, name):
.... return functools.partial(self.ActualMethod, name)
....
.... def ActualMethod(self, name, *args, **kwargs):
.... #handle *args and **kwargs based on name!
.... print name, args, kwargs
....
>>foo().bar('hello', world=1)
bar ('hello',) {'world': 1}
>>>

- Josiah
Jun 14 '07 #2


Josiah Carlson wrote:
>
Ahh, so you want to pass the method name to the method that you are
returning to be called. No problem.
>>import functools
>>>
>>class foo:
... def __getattr__(self, name):
... return functools.partial(self.ActualMethod, name)
...
... def ActualMethod(self, name, *args, **kwargs):
... #handle *args and **kwargs based on name!
... print name, args, kwargs
...
>>foo().bar('hello', world=1)
bar ('hello',) {'world': 1}
>>>
Thanks, this is exactly what I was looking for! For some reason functools didn't even show up at all during Google searches...must have just had the wrong search terms.

-Jay

Jun 14 '07 #3
Jay Loden wrote:
Josiah Carlson wrote:
>Ahh, so you want to pass the method name to the method that you are
returning to be called. No problem.
> >>import functools

class foo:
... def __getattr__(self, name):
... return functools.partial(self.ActualMethod, name)
...
... def ActualMethod(self, name, *args, **kwargs):
... #handle *args and **kwargs based on name!
... print name, args, kwargs
...
> >>foo().bar('hello', world=1)
bar ('hello',) {'world': 1}
> >>>

Thanks, this is exactly what I was looking for! For some reason functools didn't even show up at all during Google searches...must have just had the wrong search terms.
Well, the particular operation is typically called 'currying a
function', and unless you know what to look for, it isn't very easy to
make happen.

On the other hand, it is also relatively easy to implement by hand if
necessary.

- Josiah
Jun 14 '07 #4
Josiah Carlson wrote:
Well, the particular operation is typically called 'currying a
function', and unless you know what to look for, it isn't very easy to
make happen.
Replace "make happen" to "discover in the standard library".

- Josiah
Jun 15 '07 #5
Josiah Carlson a écrit :
(snip)
Well, the particular operation is typically called 'currying a
function',
<pedantic>
it's not 'currying' but 'partial application'.

Currying is somehow the reverse of partial : it's a way of building a
multiple-args function from single-args functions.
</pedantic>
Jun 15 '07 #6
Bruno Desthuilliers <br********************@wtf.websiteburo.oops.com >
wrote:
Josiah Carlson a écrit :
(snip)
Well, the particular operation is typically called 'currying a
function',

<pedantic>
it's not 'currying' but 'partial application'.

Currying is somehow the reverse of partial : it's a way of building a
multiple-args function from single-args functions.
</pedantic>
Wikipedia says "currying or Schönfinkelisation[1] is the technique of
transforming a function that takes multiple arguments into a function
that takes a single argument" -- and FWIW I agree with Wikipedia in this
case; the reverse (going from single-arg to multiple-args) would be
"uncurrying", though I don't think I've ever used that term myself.

functools.partial's name may be more precise (because it can, e.g., go
from a function taking 3 arguments to one taking 2 -- not just from N
down to 1) but your 'pedantic' remark seems pedantically wrong:-).
Alex

Jun 15 '07 #7
Alex Martelli a écrit :
Bruno Desthuilliers <br********************@wtf.websiteburo.oops.com >
wrote:
>Josiah Carlson a écrit :
(snip)
>>Well, the particular operation is typically called 'currying a
function',
<pedantic>
it's not 'currying' but 'partial application'.

Currying is somehow the reverse of partial : it's a way of building a
multiple-args function from single-args functions.
</pedantic>

Wikipedia says

"currying or Schönfinkelisation[1] "
cf below...
"is the technique of
transforming a function that takes multiple arguments into a function
that takes a single argument"
The definition commonly agreed upon (in the FP world at least) is that
currying is the process that "build" ("emulate", whatever...)
multiple-args functions in a context that only supports single-arg
functions (ie: ML, Haskell), so that (using Python syntax):

f(x, y, z)

would really be in fact (and under the hood):

f(x)(y)(z)

where f(x) returns a function closing over(x) and taking y, itself
returning a function closing over x and y and taking z...

Talking about this:
"""
currying (...) reduces multiple-argument
functions to single-argument functions only (Schoenfinkel,
1924)
"""
http://srfi.schemers.org/srfi-26/mai.../msg00015.html
So while *very closely* related to partial application, it's not exactly
the same thing.

FWIW, you can also have a look here:
http://www.python.org/dev/peps/pep-0309/#motivation
-- and FWIW I agree with Wikipedia in this
case;
I don't - and I'm not the only one:

http://lambda-the-ultimate.org/node/2266
"""
I had mistakenly learned that curry was a form of generalized partial
application from the paper : Function Currying in Scheme by Jeffrey A.
Meunier
and the Wikipedia entry (I should have known better), however I was
mildly reprimanded for making this novice mistake in a recent paper
submission to ICFP
"""
the reverse (going from single-arg to multiple-args)
Note that I didn't say "going from", but "building". The context is a
functional language where there's *no* such thing as "multiple args"
functions.

Re-reading, I can agree that my choice of words may have been a bit
poor, specially wrt/ the word "reverse". What I meant here was that
partial application is used in the context of multiple-args function to
'build' a function taking n-x arguments from a function taking n
arguments, while currying is used in the context of single-arg functions
to "emulate" multiple-args functions.
would be
"uncurrying", though I don't think I've ever used that term myself.

functools.partial's name may be more precise (because it can, e.g., go
from a function taking 3 arguments to one taking 2 -- not just from N
down to 1)

but your 'pedantic' remark seems pedantically wrong:-).
I certainly won't pretend knowing more about CS that you do, but given
the definition of currying in pep-0309 - which exactly matches the
definition I first learned when toying with Haskell -, I maintain my
pedantic remark until proven wrong - which BTW should not be overly
difficult if it happened to be the case !-)

As a last word, the original version of pep-0309 was named "curry", and
has been corrected since:

"""
It isn't function currying, but partial application. Hence the name is
now proposed to be partial().
"""
http://www.python.org/dev/peps/pep-0...and-python-dev

Jun 15 '07 #8

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

Similar topics

14
by: K. Shier | last post by:
i need to iterate through a collection of controls and set event handlers using the given control's name as a basis. in pseudocode (wishful-thinkingcode!): AddHandler BufControl.validateevent,...
7
by: pmclinn | last post by:
I was wondering if it is possible to dynamically create a structure. Something like this: public sub main sql = "Select Col1, Col2 from Table a" dim al as new arraylist al =...
1
by: Lorraine | last post by:
Hi all, I have test application written in C# from which I am trying to dynamically invoke a DLL. I have two dll's the only difference being one is written in C# and the other in VB.NET. The test...
6
by: Dan Dorey | last post by:
I actually have two questions here, but I'll start by giving an outline of what I'm trying to do. I'm building an app with a simple plugin architecture (all in the same app domain). I have each...
6
by: | last post by:
I have made some user controls with custom properties. I can set those properties on instances of my user controls, and I have programmed my user control to do useful visual things in response to...
2
by: Smithers | last post by:
Using 3.5, I am stuck in attempting to: 1. Dynamically load an assembly 2. Instantiate a class from that assembly (the client code is in a different namespace than the namespace of the...
2
by: Smithers | last post by:
I have a Windows Forms application that implements a plug-in architecture whereby required assemblies are identified and loaded dynamically. Here are the relevant classes: A = application =...
4
by: =?Utf-8?B?QWJoaQ==?= | last post by:
I am using Reflection to invoke methods dynamically. I have got a special requirement where I need to pass a value to method by setting the custom method attribute. As I cannot change the...
7
by: chage | last post by:
Hi, I have been searching around to try adding reference assembly to another assembly during runtime, programatically. Is this possible in .Net? The reason for this is because i am having...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.