472,799 Members | 1,390 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Overriding member methods in __init__

Given a condition at the time a class is instantiated, I want to change
how __call__ is used. From the example below, self.no is using self.yes
but self.__call__ is not. Can someone please explain why?

EXAMPLE:
class YesNo(object):
def __init__(self, which):
self.no = self.yes
self.__call__ = self.yes

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val

def __call__(self, val):
raise NotImplementedError()
>>y = YesNo(True)
y.yes('hello')
Yes hello
>>y.no('hello')
Yes hello
>>y('hello')
Traceback ....
Not ImplementedError

Dec 3 '07 #1
6 1333
c james a écrit :
Given a condition at the time a class is instantiated, I want to change
how __call__ is used. From the example below, self.no is using self.yes
but self.__call__ is not. Can someone please explain why?
IIRC, you can't override __magic__ methods on a per-instance basis.
EXAMPLE:
class YesNo(object):
def __init__(self, which):
self.no = self.yes
self.__call__ = self.yes

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val

def __call__(self, val):
raise NotImplementedError()

This should do the trick:

class YesNo(object):
def __init__(self, which):
self.which = which

def __call__(self, val):
return (self.no, self.yes)[self.which](val)

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val
Dec 3 '07 #2
Bruno Desthuilliers wrote:
c james a écrit :
>Given a condition at the time a class is instantiated, I want to change
how __call__ is used. From the example below, self.no is using self.yes
but self.__call__ is not. Can someone please explain why?

IIRC, you can't override __magic__ methods on a per-instance basis.
This should do the trick:

class YesNo(object):
def __init__(self, which):
self.which = which

def __call__(self, val):
return (self.no, self.yes)[self.which](val)

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val
Thanks, I was trying to eliminate another level of indirection with a
test at each invocation of __call__

Dec 3 '07 #3
c james <cj****@callone.netwrote:

Thanks, I was trying to eliminate another level of indirection with a
test at each invocation of __call__

Try using different subclasses for each variant:

class YesNo(object):
def __new__(cls, which, *args, **kw):
if cls is YesNo:
if which:
return object.__new__(Yes)
else:
return object.__new__(No)

def __init__(self, which, *args, **kw):
print "New", self.__class__, which, args, kw

def __call__(self, val):
raise NotImplementedError()
class Yes(YesNo):
def __call__(self, val):
print 'Yes', val
class No(YesNo):
def __call__(self, val):
print 'No', val

>>y = YesNo(True)
New <class '__main__.Yes'True () {}
>>y('hello')
Yes hello
>>n = YesNo(False)
New <class '__main__.No'False () {}
>>n('hello')
No hello
>>>
Dec 3 '07 #4
c james <cj****@callone.netwrites:
>class YesNo(object):
def __init__(self, which):
self.which = which

def __call__(self, val):
return (self.no, self.yes)[self.which](val)

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val

Thanks, I was trying to eliminate another level of indirection with a
test at each invocation of __call__
Allowing instance lookup of __call__ would slow down normal uses of
the internal __call__ mechanism. Since it used for all function and
method calls, it needs to remain extremely fast. If you're really
worried about performance, you can define YesNo.__new__ to return
either a Yes instance or a No instance, depending on the value:

class YesNo(object):
def __new__(cls, which):
if which:
return object.__new__(Yes)
else:
return object.__new__(No)

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val

class Yes(YesNo):
def __call__(self, val):
self.yes(val) # no check at every call

class No(YesNo):
def __call__(self, val):
self.no(val) # likewise
>>x = YesNo(True)
x
<__main__.Yes object at 0xb7d0ee8c>
>>x('foo')
Yes foo
>>y = YesNo(False)
y
<__main__.No object at 0xb7d0eeec>
>>y('foo')
No foo
>>isinstance(x, YesNo)
True
>>isinstance(y, YesNo)
True
Dec 3 '07 #5
On Dec 3, 3:36 pm, Hrvoje Niksic <hnik...@xemacs.orgwrote:
Allowing instance lookup of __call__ would slow down normal uses of
the internal __call__ mechanism. Since it used for all function and
method calls, it needs to remain extremely fast. If you're really
worried about performance, you can define YesNo.__new__ to return
either a Yes instance or a No instance, depending on the value:

class YesNo(object):
def __new__(cls, which):
if which:
return object.__new__(Yes)
else:
return object.__new__(No)

def yes(self, val):
print 'Yes', val

def no(self, val):
print 'No', val

class Yes(YesNo):
def __call__(self, val):
self.yes(val) # no check at every call

class No(YesNo):
def __call__(self, val):
self.no(val) # likewise
Why not simply do:

class YesNo(object):
def __init__(self, which):
self.yesno = which and self.yes or self.no
def yes(self, val):
print 'Yes', val
def no(self, val):
print 'No', val
def __call__(self, val):
self.yesno(val)

I don't know which is fastest but I don't think there would be much
difference.

--
Arnaud

Dec 3 '07 #6
Arnaud Delobelle wrote:
Why not simply do:

class YesNo(object):
def __init__(self, which):
self.yesno = which and self.yes or self.no
def yes(self, val):
print 'Yes', val
def no(self, val):
print 'No', val
def __call__(self, val):
self.yesno(val)

I don't know which is fastest but I don't think there would be much
difference.

--
Arnaud
This is more in the spirit of what I was trying to accomplish.
Originally, I was unaware the __call__ could not be assigned a different
method.

Dec 3 '07 #7

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

Similar topics

7
by: Alex VanderWoude | last post by:
Is there a way to override a method on a class whose source you cannot change in such a way that you can hook into that method's code? After doing some research, it appears that one way to do such...
5
by: zero | last post by:
I'm having trouble with overriding methods in subclasses. I'll explain the problem using some code: class BaseClass { protected: void method2(); public: void method1();
3
by: Sambo | last post by:
By accident I assigned int to a class member 'count' which was initialized to (empty) string and had no error till I tried to use it as string, obviously. Why was there no error on assignment( near...
4
by: Frank Millman | last post by:
Hi all Assume a simple class - class Test(object): def __init__(self,x): self.x = x def getx(self): print self.x
17
by: lm401 | last post by:
I'm trying to work with the following idea: class animal: def __init__(self, weight, colour): self.weight = weight self.colour = colour class bird(animal): def __init__(self, wingspan):
2
by: tom arnall | last post by:
George, did you ever put up your object dumper on the net? tom arnall north spit, ca usa Make cyberspace pretty: stamp out curly brackets and semicolons.
4
by: Mizipzor | last post by:
I have some troubles with a member variable that seems to be missing in a class. In short, heres what I do; class A is the parent class, B inherits from A and C inherits from B (hope I used the...
8
by: Ethan Kennerly | last post by:
Hello, There are a lot of Python mailing lists. I hope this is an appropriate one for a question on properties. I am relatively inexperienced user of Python. I came to it to prototype...
17
by: Donn Ingle | last post by:
Hi, Here's a framework for the questions: --- In a module, part of an API --- class Basis ( object ): def foo ( self, arg ): pass --- In user's own code --- class Child ( Basis ):
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?

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.