Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > CONSTRUCT - Python's way of Ruby's "alias_method"

Reply
Thread Tools

CONSTRUCT - Python's way of Ruby's "alias_method"

 
 
Ilias Lazaridis
Guest
Posts: n/a
 
      06-08-2006
I have a few small questions subjecting python functionality, most
importantly the "alias_method".

-

*IMPORT*

I would like to know, if this construct is valid, or if it can result in
problems (that I do not see as a newcomer):

1082 try:
1083 from django.rework.evolve import evolvedb
1084 except ImportError:
1085 def evolvedb():
1086 "Evolve Command Dummy"
1087 print 'Command evolvedb not imported'
1088 evolvedb.args =''

-

*PATCHING*

A second problem is, how to make the setup for users (testers) more
convenient. Is there e.g. any mechanism to apply a patch in an automated
manner (e.g. using a python library)?

-

*ALIAS_METHOD*

The django commands are hard-coded:

http://code.djangoproject.com/browse...ement.py#L1180

thus elegant/dynamic additions of commands seem not possible.

Another possibility is to enlink (hook?) the functionality into an
existent function

Is there any way (beside a patch) to alter the behaviour to an existing
function. Is ther a python construct similar to the "alias_method" of Ruby:

(example from an simple evolution support for a ruby orm)

#------------------------------------------------------------------------------
# use "alias_method" to enlink the code
#------------------------------------------------------------------------------

class SqliteAdapter
alias_method ld_create_table, :create_table
def create_table(*args)
table_evolve(*args)
result = old_create_table(*args)
return result
end
end

http://lazaridis.com/case/persist/og-evolve.rb

-
-
-

If anyone is interested to verify the results in order to stabelize the
simple schema evolution support for django, please review the results
here:

http://case.lazaridis.com/wiki/DjangoProductEvaluation
http://case.lazaridis.com/wiki/DjangoSchemaEvolution
http://case.lazaridis.com/browser/dj...work/evolve.py
http://case.lazaridis.com/browser/dj...b_command.diff

..

--
http://lazaridis.com
 
Reply With Quote
 
 
 
 
Maric Michaud
Guest
Posts: n/a
 
      06-08-2006
Le Jeudi 08 Juin 2006 14:28, Ilias Lazaridis a écrit*:
> Another possibility is to enlink (hook?) the functionality into an
> existent function
>
> Is there any way (beside a patch) to alter the behaviour to an existing
> function. Is ther a python construct similar to the "alias_method" of Ruby:
>

No, there is no special construct to do this, but we do things very similar
every day in Zope, it's called "monkey patch" :

#patch_service.py
from toto import service

def my_impl(self, *args) :
old_result = self._old_method(*args)
# ...
return new_result

if not hasattr(service, '_old_method') :
service._old_method = service.method
service.method = my_impl

once this file is imported, all future calls to "method" of service instances
will use my_impl.

--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
Reply With Quote
 
 
 
 
Tim N. van der Leeuw
Guest
Posts: n/a
 
      06-08-2006
Since your question is so much about Django, you might want to ask on
Django groups.

Oops, you're not welcome there anymore, almost forgot.

But if merely reading the subject of a posting I already know who's the
poster, it's perhaps a bad sign.

Further readers of this thread might be interested in the discussions
linked from these pages:

http://en.wikipedia.org/wiki/Ilias_Lazaridis
http://www.encyclopediadramatica.com/index.php/Ilias
http://groups.google.com/group/comp....6315fda51d50a1

EOT?

 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      06-08-2006
Ilias Lazaridis wrote:

> Is there any way (beside a patch) to alter the behaviour to an
> existing function. Is ther a python construct similar to the
> "alias_method" of Ruby:


This is a Python list. Would you care to explain what alias_method does?

>
> (example from an simple evolution support for a ruby orm)
>
> #----------------------------------------------------------------------
> -------- # use "alias_method" to enlink the code
> #----------------------------------------------------------------------
> --------
>
> class SqliteAdapter
> alias_method ld_create_table, :create_table
> def create_table(*args)
> table_evolve(*args)
> result = old_create_table(*args)
> return result
> end
> end
>


This looks like alias_method does nothing much more than an assignment. If
you want to override a method in a base class then you can do it something
like:

class SqliteAdapter(BaseClass):
old_create_table = BaseClass.create_table
def create_table(self, *args)
self.table_evolve(*args)
result = self.old_create_table(*args)
return result

but the more usual way is just to call the original method directly in the
base class.

class SqliteAdapter(BaseClass):
def create_table(self, *args)
self.table_evolve(*args)
result = BaseClass.create_table(self, *args)
return result

If that isn't what you are trying to achieve you'll have to explain more.
 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      06-08-2006
Ilias Lazaridis wrote:

> I would like to know, if this construct is valid, or if it can result in
> problems (that I do not see as a newcomer):
>
> 1082 try:
> 1083 from django.rework.evolve import evolvedb
> 1084 except ImportError:
> 1085 def evolvedb():
> 1086 "Evolve Command Dummy"
> 1087 print 'Command evolvedb not imported'
> 1088 evolvedb.args =''


The only real problem here is that if django.rework.evolve imports
something else which doesn't exist you get your fallback code instead of
reporting the error. In other words there is a chance that you could mask a
deeper problem.

If this worries you then you could do:

try:
from django.rework.evolve import evolvedb
except ImportError, e:
if str(e).rsplit(' ')[-1] != 'django.rework.evolve':
raise
... rest of code here ...
 
Reply With Quote
 
Maric Michaud
Guest
Posts: n/a
 
      06-08-2006
Le Jeudi 08 Juin 2006 15:15, Duncan Booth a écrit :
> but the more usual way is just to call the original method directly in the
> base class.
>
> class SqliteAdapter(BaseClass):
> def create_table(self, *args)
> self.table_evolve(*args)
> result = BaseClass.create_table(self, *args)
> return result
>


Yeah, this the right way to reuse ancestor's implementation of a method.

> If that isn't what you are trying to achieve you'll have to explain more.

I'm not a ruby programmer, but I understood it like this : the prupose is to
modify the behavior of an existing third-party class, in all application
(even in existing third party modules), without any code modifications
(traditional patch) in those modules.

Your proposal is not as good here, assuming BaseClass is defined in module
toto, you can still do toto.BaseClass = SqliteAdapter, but you must ensure
that this code is imported before any other where classes inherit from
BaseClass. The one I porpose in my other post is robust, several packages can
even patch the same method with no side effects.


--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
Reply With Quote
 
Ilias Lazaridis
Guest
Posts: n/a
 
      06-08-2006
Tim N. van der Leeuw wrote:
[...]

http://case.lazaridis.com/wiki/Please

..

--
http://lazaridis.com
 
Reply With Quote
 
Ilias Lazaridis
Guest
Posts: n/a
 
      06-08-2006
Maric Michaud wrote:
> Le Jeudi 08 Juin 2006 15:15, Duncan Booth a écrit :
>> but the more usual way is just to call the original method directly in the
>> base class.
>>
>> class SqliteAdapter(BaseClass):
>> def create_table(self, *args)
>> self.table_evolve(*args)
>> result = BaseClass.create_table(self, *args)
>> return result
>>

>
> Yeah, this the right way to reuse ancestor's implementation of a method.
>
>> If that isn't what you are trying to achieve you'll have to explain more.

> I'm not a ruby programmer, but I understood it like this : the prupose is to
> modify the behavior of an existing third-party class, in all application
> (even in existing third party modules), without any code modifications
> (traditional patch) in those modules.


yes, you've understood right.

> Your proposal is not as good here, assuming BaseClass is defined in module
> toto, you can still do toto.BaseClass = SqliteAdapter, but you must ensure
> that this code is imported before any other where classes inherit from
> BaseClass. The one I porpose in my other post is robust, several packages can
> even patch the same method with no side effects.


Your suggestion is most possibly the relevant construct.

I'll post a note after changing the implementation.

Thank's a lot!

..

--
http://lazaridis.com
 
Reply With Quote
 
Ilias Lazaridis
Guest
Posts: n/a
 
      06-08-2006
Duncan Booth wrote:
> Ilias Lazaridis wrote:
>
>> I would like to know, if this construct is valid, or if it can result in
>> problems (that I do not see as a newcomer):
>>
>> 1082 try:
>> 1083 from django.rework.evolve import evolvedb
>> 1084 except ImportError:
>> 1085 def evolvedb():
>> 1086 "Evolve Command Dummy"
>> 1087 print 'Command evolvedb not imported'
>> 1088 evolvedb.args =''

>
> The only real problem here is that if django.rework.evolve imports
> something else which doesn't exist you get your fallback code instead of
> reporting the error. In other words there is a chance that you could mask a
> deeper problem.
>
> If this worries you then you could do:
>
> try:
> from django.rework.evolve import evolvedb
> except ImportError, e:
> if str(e).rsplit(' ')[-1] != 'django.rework.evolve':
> raise
> ... rest of code here ...


I thin I understand.

If the exception is _not_ caused by 'django.rework.evolve', then it will
be raised, thus I can see what caused it.

Very nice!

..

--
http://lazaridis.com
 
Reply With Quote
 
Slawomir Nowaczyk
Guest
Posts: n/a
 
      06-08-2006
On Thu, 08 Jun 2006 06:05:35 -0700
"Tim N. van der Leeuw" <> wrote:

#> Since your question is so much about Django, you might want to ask
#> on Django groups.

Now *that*, and the rest of your post, was uncalled for.

This thread is perfectly on topic for this list and the question asked
concerns *Python*, with django being only a use case.

--
Best wishes,
Slawomir Nowaczyk
( )

Some drink at the fountain of knowledge. Others just gargle.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Behavior of if construct in switch case defualt construct. Mukesh C Programming 4 03-26-2010 12:38 PM
Any elegant way to construct the complete $k$-partite graph inPython? Paul Miller Python 6 11-24-2009 01:02 PM
Best way to construct an email - attach a html file and send a Python 6 08-23-2006 10:17 PM
Fastest way to construct this class Ninan C++ 2 04-18-2006 05:39 PM
way way way OT: MCNGP Announcement Neil MCSE 174 04-17-2006 05:55 PM



Advertisments