I'm building a class hierarchy that needs to keep as a class variable a
reference to a (non-member) function, so that different subclasses can
use different generator functions. But it seems Python is treating the
function as a member function because the reference to it is in class
scope....
Here's a simple case of what I'm trying (in the real code, fn is a
function that returns a database connection relevant to that subclass): def foo(): print "foo called"
class S(object): fn = foo
def bar(cls): cls.fn() bar = classmethod(bar )
def foo2(): print "foo2 called"
class D(S): fn = foo2
D.bar()
[I'm on python 2.3.4 so no @classmethod decorator! ]
When I run this:
Traceback (most recent call last): File "t_o.py", line 19, in ? D.bar() File "t_o.py", line 10, in bar cls.fn() TypeError: unbound method foo2() must be called with D instance as first argument (got nothing instead)
This shows it is trying to do what I expect (call foo2()) but somehow
the type is all wrong.
I've tried playing with staticmethod() but I can't quite get it all
worked out... 3 1714
Gregory Bond wrote: I'm building a class hierarchy that needs to keep as a class variable a reference to a (non-member) function, so that different subclasses can use different generator functions. But it seems Python is treating the function as a member function because the reference to it is in class scope....
Here's a simple case of what I'm trying (in the real code, fn is a function that returns a database connection relevant to that subclass):
def foo(): print "foo called"
class S(object): fn = foo
def bar(cls): cls.fn() bar = classmethod(bar )
def foo2(): print "foo2 called"
class D(S): fn = foo2
D.bar()
I've tried playing with staticmethod() but I can't quite get it all worked out...
You are on the right track with staticmethod, but you have to apply it to
fn: def foo(): print "first foo"
.... def foo2(): print "second foo"
.... class S(object):
.... fn = staticmethod(fo o)
.... def bar(cls):
.... cls.fn()
.... bar = classmethod(bar )
.... class D(S):
.... fn = staticmethod(fo o2)
.... S.bar()
first foo D.bar()
second foo
In its current form, the bar() method is not necessary:
S.fn()
first foo D.fn()
second foo
Peter
Peter Otten wrote: You are on the right track with staticmethod, but you have to apply it to fn:
... fn = staticmethod(fo o)
Thanks Peter, that's a big help.
I can solve my problem now, but I'm chasing this further in the name of
education, because it seems there is some deep magic happening here that
I don't understand.
It seems that applying staticfunction( ) (or perhaps assigning to the
class object) is treated differently if it happens in the class
defininition, to when it happens at "run time". (My previous attempts
to get staticmember() to do the right thing were all "run time" like the
examples below.)
Say I wanted to keep the need for "staticmemb er" hidden from subclasses,
and do the staticmember() conversion in the base class methods. I've
tried 2 ways of doing this (no subclassing here, just to keep it simple):
class B(object): fn = foo def try1(self): print "B.fn is", type(B.fn) B.fn = staticmethod(B. fn) print "B try1" print "B.fn is now", type(B.fn) B.fn()
def try2(self): fn2 = staticmethod(B. fn) print "B try2" print "fn2 is now", type(fn2) fn2()
If I try method 1 (assigning to the class object - ignore for a moment
the problem of only doing this once!) I get a set of very surprising
results:
B.fn is <type 'instancemethod '> B try1 B.fn is now <type 'instancemethod '> Traceback (most recent call last): File "t_o1.py", line 28, in ? B().try1() File "t_o1.py", line 17, in try1 B.fn() TypeError: unbound method foo() must be called with B instance as first argument (got nothing instead)
note that assigning the staticmember() result to B.fn does NOT change
the type of B.fn!! And foo is treated as a member function.
So if I try method 2 (using staticmethod() at runtime):
B try2 fn2 is now <type 'staticmethod'> Traceback (most recent call last): File "t_o1.py", line 27, in ? B().try2() File "t_o1.py", line 22, in try2 fn2() TypeError: 'staticmethod' object is not callable
fn2 is a static method, as I'd expect, but it is somehow not callable?
Can someone explain what is going on here? Pointers to language spec,
code, PEPs etc gladly accepted.
Greg,
caught in a twisty little maze of descriptors, all different!
Gregory Bond wrote: Thanks Peter, that's a big help.
You're welcome.
I can solve my problem now, but I'm chasing this further in the name of education, because it seems there is some deep magic happening here that I don't understand.
Python resorts to deep magic only when it's inevitable, i. e. hardly
ever :-)
It seems that applying staticfunction( ) (or perhaps assigning to the class object) is treated differently if it happens in the class defininition, to when it happens at "run time". (My previous attempts to get staticmember() to do the right thing were all "run time" like the examples below.)
There is no distinction between "run time" and "class definition time". The
class "body" is actually a function that is called when the module is
loaded. Its locals() are then used to create a type instance, i. e. the
class.
Say I wanted to keep the need for "staticmemb er" hidden from subclasses, and do the staticmember() conversion in the base class methods. I've tried 2 ways of doing this (no subclassing here, just to keep it simple):
class B(object): fn = foo def try1(self): print "B.fn is", type(B.fn) B.fn = staticmethod(B. fn) print "B try1" print "B.fn is now", type(B.fn) B.fn()
def try2(self): fn2 = staticmethod(B. fn) print "B try2" print "fn2 is now", type(fn2) fn2() If I try method 1 (assigning to the class object - ignore for a moment the problem of only doing this once!) I get a set of very surprising results:
B.fn is <type 'instancemethod '> B try1 B.fn is now <type 'instancemethod '> Traceback (most recent call last): File "t_o1.py", line 28, in ? B().try1() File "t_o1.py", line 17, in try1 B.fn() TypeError: unbound method foo() must be called with B instance as first argument (got nothing instead)
note that assigning the staticmember() result to B.fn does NOT change the type of B.fn!! And foo is treated as a member function.
So if I try method 2 (using staticmethod() at runtime):
B try2 fn2 is now <type 'staticmethod'> Traceback (most recent call last): File "t_o1.py", line 27, in ? B().try2() File "t_o1.py", line 22, in try2 fn2() TypeError: 'staticmethod' object is not callable
fn2 is a static method, as I'd expect, but it is somehow not callable?
Your problems stem from the fact that attribute assignment to a class
doesn't always roundtrip: A.value = 42 A.value
42 def f(): pass
.... A.method = f A.method, f
(<unbound method A.f>, <function f at 0x4028eae4>)
If a class attribute is a descriptor i. e. it has a __get__() method (which
pure python functions do) A.method is not just a dictionary lookup but a
call
A.__dict__["method"].__get__(None, A)
This is slightly simplified as it doesn't take inheritance into account.
__get__() is free to apply whatever magic, but staticmethod just gives back
the original function whereas a some_func.__get __(None, SomeClass) gives
you an unbound method:
staticmethod(f) .__get__(None, A)
<function f at 0x4028eae4> f.__get__(None, A)
<unbound method A.f>
Is there a way to get the original function back out of the unbound method?
Let's see:
dir(A.method)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
'__getattribute __', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__' , '__repr__', '__setattr__', '__str__', 'im_class',
'im_func', 'im_self']
im_func seems promising:
A.method.im_fun c
<function f at 0x4028eae4>
Can someone explain what is going on here? Pointers to language spec, code, PEPs etc gladly accepted.
Greg, caught in a twisty little maze of descriptors, all different!
The two relevant documents are http://users.rcn.com/python/download/Descriptor.htm http://www.python.org/2.2.1/descrintro.html
Peter This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Shozi |
last post by:
Dear All,
My project is basically about the personal record keeping of user's
data. Now user can customize their data entry form by adding/removing
the desired fields for personal information (e.g. Add: Home Phone Pin
Code, Remove: Personal ID Card No). All this was being done in
database and was working fine.
Some one recommend me to use DTD/XML to automate this whole process in
a standardized way. I started off while searching on...
|
by: SoloCDM |
last post by:
How do I keep my entire web page at a fixed width?
*********************************************************************
Signed,
SoloCDM
|
by: Dr.Tube |
last post by:
Hi there,
I have this web site (www.DrTube.com) which has the following DTD:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
which switches Mozilla to standards compliance mode as I can confirm
myself. How can I check whether IE6 and Opera do so too?
TIA
Regards
Xavier van Unen.
|
by: Dan |
last post by:
When a user clicks on a link in my menu, I want the background color
of the link that comes up in the hover to remain on the destination
page.
My menu looks like this:
<div id="adminmenu">
<a class="mainlink mainlink1" href="">Events</a><br>
<a class="mainlink mainlink2" href="">Home Page Teaser</a><br>
<a class="mainlink mainlink3" href="">Testimonials</a><br>
<a class="mainlink mainlink4" href="">Repertoire</a><br>
|
by: BarryS |
last post by:
Hi All:
We're rolling out 3 DB2 (8.2 on LUW) platforms for branch offices, each
of these are going to have the same schema. These are all going to be
non-federated systems.
I need some advice / pointers on keeping the DDL's in sync with each other.
I'm going to have a development machine in my office that I first apply
any schema / stored-procedure changes to, then would like to roll out
| |
by: pinkfloydhomer |
last post by:
Please read the example below. I'm sorry I couldn't make it smaller,
but it is pretty simple.
When client code is calling newThingy(), it is similar to malloc: the
client gets a pointer to a chunk of memory that it can use for it's own
purposes.
But on the "library" side, I want to be able to do some book-keeping
for each memory block that I hand out. I want some "hidden" meta-data
(that I keep in struct Container) to be associated...
|
by: pb648174 |
last post by:
I've been doing a bit of reading and have read in quite a few places
that an identity column is a good clustered index and that all or at
least most tables should have a clustered index. The tool I used to
generate tables made them all with non clustered indexes so I would
like to drop all of them and generate clustered indexes. So my
questions is a) good idea? and b) how? There are foreign key references
to most of them so those would...
|
by: Sjef |
last post by:
I am trying to understand the deeper meanings of containers. One would say:
everything inside the container div will stay inside, but apparently that's
not true.
My test code is below. When I run this in IE everything seems fine, when I
run it in Firefox the text runs out of the right box and the right box runs
out of the overall container. I don't understand the reason for this??? I
would like to make both columns the same height while...
|
by: =?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= |
last post by:
PEP 1 specifies that PEP authors need to collect feedback from the
community. As the author of PEP 3131, I'd like to encourage comments
to the PEP included below, either here (comp.lang.python), or to
python-3000@python.org
In summary, this PEP proposes to allow non-ASCII letters as
identifiers in Python. If the PEP is accepted, the following
identifiers would also become valid as class, function, or
variable names: Löffelstiel,...
|
by: Thomas Christensen |
last post by:
This issue has been raised a couple of times I am sure. But I have yet
to find a satisfying answer.
I am reading from a subprocess and this subprocess sometimes hang, in
which case a call to read() call will block indefinite, keeping me from
killing it.
The folloing sample code illustrates the problem:
proc = subprocess.Popen(,
|
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
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,...
|
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...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
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...
|
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...
| |
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |