Re: staticmethod and namespaces
Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: - So basically I added a list of instances to the base class so I can get at them from the staticmethod. Have you tried using a closure, something like this: class A: def call(self, args): def callback(a, b): # normal function # but I can access self here too call_the_dll_function(callback, args1, args2...) What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( -- дамјан ((( http://damjan.softver.org.mk/ ))) Q: What's tiny and yellow and very, very, dangerous? A: A canary with the super-user password. -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
darnzen wrote: Well, I got around this mess by putting all those static callbacks into a separate module in a new class. I set them up to call a bound method of that class which passes the arguments to the appropriate bound methods of other class instances. I just have to keep a little dict of the bound method callbacks when I register them with the class. You're making it much more complicated than it needs to be. Diez is right, a bound method should work provided you keep a reference to it somewhere for as long as it's needed. -- Greg -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Feb 26, 3:15 am, Diez B. Roggisch de...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K*facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function @staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K *facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function @staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Feb 26, 1:12 am, Steven D'Aprano st...@remove-this- cybersource.com.au wrote: On Thu, 25 Feb 2010 21:07:55 -0800, darnzen wrote: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. [...] How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Pass the instance explicitly: class K(object): ... @staticmethod ... def static(self, x, y): ... print self, x, y ... k = K() k.static(k, 1, 2) __main__.K object at 0xb7c2544c 1 2 -- Steven Unfortunately, since the callback is from the DLL which I didn't write, I can not change what is passed to the function. Also, the DLL has no idea about my local namespace. The DLL typically will pass back two integers (which I can set the values of when I register the callback), and some data. Currently Im' using these integers as keys in a local dict where I'm storing the instances. I suppose I could use the integers to store the high and low order bytes of a pointer to the instance, but not sure how to do that in Python (would be easy in c/c++). Also, I'm not sure how python memory management works, if it will move objects around and make things buggy. Also, that is definitely a hack and isn't very 'pythonesque' -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Feb 26, 9:41 am, Diez B. Roggisch de...@nospam.web.de wrote: Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) �...@staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K *facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function �...@staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez This was originally how my code was set up, invoking with the bound methods, but it didn't work (crashing and bizzaro errors) and I was pulling my hair out. Then I read the documentation and changed it to static methods and everything started working. Believe me, I totally understand how using bound methods would make this problem go away. -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Feb 26, 9:41 am, Diez B. Roggisch de...@nospam.web.de wrote: Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) �...@staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K *facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function �...@staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez Thinking about it some more, I believe I understand why it has to be staticfunction. To use an bound method would require the wrapper to include a reference to the instance as follows: A.expCallback = WINFUNCTYPE(None, POINTER(A), c_int, c_int, \ POINTER(Data_s))(a.Callback) Since a = A(); a.foo() is really A.foo(self). The problem here is that A is not a ctypes object and I can't change what arguments the DLL uses in the callback in any case. Rewording my thoughts: a bound method callback would require 'self' to be the first argument. I can not make the DLL include 'self' as it doesn't know anything about the objects in my program. Since I can't pass 'self', it has to be a staticmethod. -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
Am 26.02.10 16:57, schrieb darnzen: On Feb 26, 9:41 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.dewrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K*facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function @staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez Thinking about it some more, I believe I understand why it has to be staticfunction. To use an bound method would require the wrapper to include a reference to the instance as follows: A.expCallback = WINFUNCTYPE(None, POINTER(A), c_int, c_int, \ POINTER(Data_s))(a.Callback) Since a = A(); a.foo() is really A.foo(self). The problem here is that A is not a ctypes object and I can't change what arguments the DLL uses in the callback in any case. Rewording my thoughts: a bound method callback would require 'self' to be the first argument. I can not make the DLL include 'self' as it doesn't know anything about the objects in my program. Since I can't pass 'self', it has to be a staticmethod. No, that's not true. A bound method implictly knows about it self, and it's a callable. What I guess is that you did the same mistake I did when I created that example - namely, not keeping a refernce to the bound method around. Ctypes will then garbage-collect the callback, which of course leads to all kinds of troubles. Try this: a = A() # keep this around bound_m =
Re: staticmethod and namespaces
Am 26.02.10 17:08, schrieb Diez B. Roggisch: Am 26.02.10 16:57, schrieb darnzen: On Feb 26, 9:41 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K *facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function @staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez Thinking about it some more, I believe I understand why it has to be staticfunction. To use an bound method would require the wrapper to include a reference to the instance as follows: A.expCallback = WINFUNCTYPE(None, POINTER(A), c_int, c_int, \ POINTER(Data_s))(a.Callback) Since a = A(); a.foo() is really A.foo(self). The problem here is that A is not a ctypes object and I can't change what arguments the DLL uses in the callback in any case. Rewording my thoughts: a bound method callback would require 'self' to be the first argument. I can not make the DLL include 'self' as it doesn't know anything about the objects in my program. Since I can't pass 'self', it has to be a staticmethod. No, that's not true. A bound method implictly knows about it self, and it's a callable. What I guess is that you did the same mistake I did when I created that example - namely, not keeping a refernce to the bound method around. Ctypes will then garbage-collect the callback, which of course leads to all kinds of troubles. Try this: a = A() # keep this around bound_m = a.expCallback DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) HHRG, same error again. Of course, use DLLSetCallback(self.hID, A.SubID, EVENTID, bound_m) because the bound method changes with each time you create it. Sorry for the confusion. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Feb 26, 10:20 am, Diez B. Roggisch de...@nospam.web.de wrote: Am 26.02.10 17:08, schrieb Diez B. Roggisch: Am 26.02.10 16:57, schrieb darnzen: On Feb 26, 9:41 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 16:32, schrieb darnzen: On Feb 26, 3:15 am, Diez B. Roggischde...@nospam.web.de wrote: Am 26.02.10 06:07, schrieb darnzen: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( Can you show how you pass the staticmethod to the C-function? Is the DLL utilized by ctypes? I don't see any reason you couldn't use a bound method, which would give you your self, instead relying on global state. Diez __main__.K *facepalm* should of tried that! Yeah I'm using ctypes. The DLL callback set ups are as follows. The local callback is in the App namespace (in this case, some callbacks are in different modules as noted in OP), but still no access to self: #Function wrapper A.expCallback = WINFUNCTYPE(None, c_int, c_int, \ POINTER(Data_s))(A.Callback) #DLL call to register the local callback function DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback) class A: #Local callback function @staticmethod def Callback(hID, SubID, Data): print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!' print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT' print 'IF I STORE A REFERENCE TO MYSELF IN A DICT' print 'USING KEY GENERATED FROM hID, SubID' pass I'm not sure why they need to be static callbacks, but the DLL doc's say when using object based languages, such as c++, callback functions must be declared as static functions and not instance methods, and I couldn't get it to work without setting it up that way. I could probably have them all be classless functions, but with 100's of these, my namespace would be polluted up the wazoo, and I'd still have the problem that they wouldn't have access to instance methods / properties. The above code can't work with self, because you use A.expCallback which at best can of course be a classmethod. You need to instead invoke DLLSetCallback with a bound method, like this a = A() DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods. Diez Thinking about it some more, I believe I understand why it has to be staticfunction. To use an bound method would require the wrapper to include a reference to the instance as follows: A.expCallback = WINFUNCTYPE(None, POINTER(A), c_int, c_int, \ POINTER(Data_s))(a.Callback) Since a = A(); a.foo() is really A.foo(self). The problem here is that A is not a ctypes object and I can't change what arguments the DLL uses in the callback in any case. Rewording my thoughts: a bound method callback would require 'self' to be the first argument. I can not make the DLL include 'self' as it doesn't know anything about the objects in my program. Since I can't pass 'self', it has to be a staticmethod. No, that's not true. A bound method implictly knows about it self, and it's a callable. What I guess is that you did the same mistake I did when I created that example - namely, not keeping a refernce to the bound method around. Ctypes will then garbage-collect the callback, which of course leads to all kinds of troubles. Try this: a = A() # keep this around bound_m = a.expCallback DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback) HHRG, same error again. Of course, use
staticmethod and namespaces
Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It will make more sense after I diagram it: #Module main.py class App: def sperg(self): pass app = App() [main loop and such] - # Module A.py import main class Foo: @staticmethod chum(nType, nPtr): # Need to access function / data in app instance app.sperg(nType, nPtr) -- http://mail.python.org/mailman/listinfo/python-list
staticmethod and namespaces
Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. It could be import related? It will make more sense after I diagram it: #Module main.py from A import * class App: def sperg(self): self.a = A() app = App() [main loop and such] - # Module A.py import main class Foo: Selves=[] def __init__(self): Foo.Selves.append(self) @staticmethod def chum_callback(nType, nP): # Need to access function / data in app instance app.sperg(nP) # Need to access func data in Foo # I'm pulling 'self' ouf of list made in constructor self = Foo.getSelf(nP) def getSelf(nP): return self.Selves[nP] - So basically I added a list of instances to the base class so I can get at them from the staticmethod. What's bothering me the most is I can't use the global app instance in the A.py module. How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Sorry for the double / partial post :( -- http://mail.python.org/mailman/listinfo/python-list
Re: staticmethod and namespaces
On Thu, 25 Feb 2010 21:07:55 -0800, darnzen wrote: Having an odd problem that I solved, but wondering if its the best solution (seems like a bit of a hack). First off, I'm using an external DLL that requires static callbacks, but because of this, I'm losing instance info. [...] How can I get at the app instance (currently I'm storing that along with the class instance in the constructor)? Is there another way to do this that's not such a hack? Pass the instance explicitly: class K(object): ... @staticmethod ... def static(self, x, y): ... print self, x, y ... k = K() k.static(k, 1, 2) __main__.K object at 0xb7c2544c 1 2 -- Steven -- http://mail.python.org/mailman/listinfo/python-list