Python:如果静态 class 变量获得不同的函数引用指针,如何解决?
Python: How to fix, if a static class variable gets a different function reference pointer?
我想知道为什么我的 class 调用带有参数的引用函数(分配给静态 class 变量)。如果我将函数引用分配给普通 class 变量,它会像预期的那样工作。
这是我的示例代码:
# This function is not editable, because it's imported from an API
def getStuff():
print "I do my stuff!!!"
class foo(object):
GET_STUFF = getStuff
def __init__(self):
print "static var: ",self.GET_STUFF
self.GET_STUFF()
print "outer func: ",getStuff
foo()
出现以下错误:
outer func: <function getStuff at 0x0000000003219908>
static var: <bound method foo.getStuff of <__main__.foo object at 0x00000000030AB358>>
Traceback (most recent call last):
File "C:/example.py", line 13, in <module>
foo()
File "C:/example.py", line 10, in __init__
self.GET_STUFF()
TypeError: getStuff() takes no arguments (1 given)
为了解决这个问题,我将构造函数中的函数引用指向 class 变量:
class foo(object):
def __init__(self):
self.GET_STUFF = getStuff
print "static var: ",self.GET_STUFF
self.GET_STUFF()
结果如预期,工作正常:
outer func: <function getStuff at 0x000000000331F908>
static var: <function getStuff at 0x000000000331F908>
I do my stuff!!!
但是:
我想使用静态 class 变量,因为它易于阅读,并且易于为不同的 API 设置。所以最后我会想出一些包装器 classes,如下所示:
from API01 import getStuff01
from API02 import getStuff02
# bar calculates stuff object from the API (it calls GET_STUFF)
# and stores the object into self.stuff
import bar
class foo01(bar):
GET_STUFF = getStuff01
def DoSomething(self, volume):
self.stuff.volume = volume
class foo02(bar):
GET_STUFF = getStuff02
def DoSomething(self, volume):
self.stuff.volume = volume
# [...] and so on..
有没有办法让它以我想要设置包装器的方式工作 classes,或者我真的必须为每个包装器定义一个构造函数 class?
谢谢
错误的原因是
self.GET_STUFF()
其实就是
tmp = getattr(self, 'GET_STUFF')
tmp(self)
这意味着这两个class是等价的:
def foo(self): pass
class Foo(object):
a = foo
class Bar(object):
def a(self): pass
在这两种情况下,函数对象作为成员添加到 class,这意味着对于 Python,函数需要 self
作为第一个参数。
实现你想要的:
from API01 import getStuff01
def wrapper01(self):
getStuff01()
class foo01(object):
GET_STUFF = wrapper01
只是为了扩展 Aaron 的回答,如果你想拥有静态方法,你可以使用 @staticmethod 装饰器:
class Calc:
@staticmethod
def sum(x, y):
return x + y
print (Calc.sum(3,4))
>>> 7
我已经想到我的对象正在调用引用的函数并将其自身作为参数。经过一番研究,我终于找到了解决方案。当我使用 class 变量指向函数时,它不会引用直接指针。它将函数引用为 class 的反弹方法。要摆脱使用 getattr
调用方法的默认调用,必须覆盖 class 本身的 getattr
调用函数(在本例中 class bar
,因为 foo
(包装器 classes)继承了 bar
:
的功能
import inspect
class bar(object):
GET_STUFF = None
def __getattribute__(self, name):
attr = object.__getattribute__(self,name)
if name == "GET_STUFF":
# Check: is method and is bounced?
if inspect.ismethod(attr) and attr.im_self is not None:
return attr.__func__
return attr
bar
的 getattr
现在指向原始函数引用,但仅针对 class 变量 GET_STUFF
,因为我想保留默认功能我的其余变量。
所以,当我现在执行以下命令时:
class foo(bar):
GET_STUFF = getStuff
def __init__(self):
print "inner func: ",self.GET_STUFF
self.GET_STUFF()
foo()
我得到了预期的结果,并且可以编写我的包装器,而无需使用这些包装器为每个模块生成额外的代码 classes:
outer func: <function getStuff at 0x00000000034259E8>
inner func: <function getStuff at 0x00000000034259E8>
I do my stuff!!!
我想知道为什么我的 class 调用带有参数的引用函数(分配给静态 class 变量)。如果我将函数引用分配给普通 class 变量,它会像预期的那样工作。
这是我的示例代码:
# This function is not editable, because it's imported from an API
def getStuff():
print "I do my stuff!!!"
class foo(object):
GET_STUFF = getStuff
def __init__(self):
print "static var: ",self.GET_STUFF
self.GET_STUFF()
print "outer func: ",getStuff
foo()
出现以下错误:
outer func: <function getStuff at 0x0000000003219908>
static var: <bound method foo.getStuff of <__main__.foo object at 0x00000000030AB358>>
Traceback (most recent call last):
File "C:/example.py", line 13, in <module>
foo()
File "C:/example.py", line 10, in __init__
self.GET_STUFF()
TypeError: getStuff() takes no arguments (1 given)
为了解决这个问题,我将构造函数中的函数引用指向 class 变量:
class foo(object):
def __init__(self):
self.GET_STUFF = getStuff
print "static var: ",self.GET_STUFF
self.GET_STUFF()
结果如预期,工作正常:
outer func: <function getStuff at 0x000000000331F908>
static var: <function getStuff at 0x000000000331F908>
I do my stuff!!!
但是:
我想使用静态 class 变量,因为它易于阅读,并且易于为不同的 API 设置。所以最后我会想出一些包装器 classes,如下所示:
from API01 import getStuff01
from API02 import getStuff02
# bar calculates stuff object from the API (it calls GET_STUFF)
# and stores the object into self.stuff
import bar
class foo01(bar):
GET_STUFF = getStuff01
def DoSomething(self, volume):
self.stuff.volume = volume
class foo02(bar):
GET_STUFF = getStuff02
def DoSomething(self, volume):
self.stuff.volume = volume
# [...] and so on..
有没有办法让它以我想要设置包装器的方式工作 classes,或者我真的必须为每个包装器定义一个构造函数 class?
谢谢
错误的原因是
self.GET_STUFF()
其实就是
tmp = getattr(self, 'GET_STUFF')
tmp(self)
这意味着这两个class是等价的:
def foo(self): pass
class Foo(object):
a = foo
class Bar(object):
def a(self): pass
在这两种情况下,函数对象作为成员添加到 class,这意味着对于 Python,函数需要 self
作为第一个参数。
实现你想要的:
from API01 import getStuff01
def wrapper01(self):
getStuff01()
class foo01(object):
GET_STUFF = wrapper01
只是为了扩展 Aaron 的回答,如果你想拥有静态方法,你可以使用 @staticmethod 装饰器:
class Calc:
@staticmethod
def sum(x, y):
return x + y
print (Calc.sum(3,4))
>>> 7
我已经想到我的对象正在调用引用的函数并将其自身作为参数。经过一番研究,我终于找到了解决方案。当我使用 class 变量指向函数时,它不会引用直接指针。它将函数引用为 class 的反弹方法。要摆脱使用 getattr
调用方法的默认调用,必须覆盖 class 本身的 getattr
调用函数(在本例中 class bar
,因为 foo
(包装器 classes)继承了 bar
:
import inspect
class bar(object):
GET_STUFF = None
def __getattribute__(self, name):
attr = object.__getattribute__(self,name)
if name == "GET_STUFF":
# Check: is method and is bounced?
if inspect.ismethod(attr) and attr.im_self is not None:
return attr.__func__
return attr
bar
的 getattr
现在指向原始函数引用,但仅针对 class 变量 GET_STUFF
,因为我想保留默认功能我的其余变量。
所以,当我现在执行以下命令时:
class foo(bar):
GET_STUFF = getStuff
def __init__(self):
print "inner func: ",self.GET_STUFF
self.GET_STUFF()
foo()
我得到了预期的结果,并且可以编写我的包装器,而无需使用这些包装器为每个模块生成额外的代码 classes:
outer func: <function getStuff at 0x00000000034259E8>
inner func: <function getStuff at 0x00000000034259E8>
I do my stuff!!!