我想定义一个包含read
和write
方法的类,可以按如下方式调用:
instance.read
instance.write
instance.device.read
instance.device.write
为了不使用隔行扫描类,我的想法是覆盖__getattr__
和__setattr__
方法并检查,如果给定名称为device
,则将返回值重定向到{{1} }。但是我遇到了一个无限递归的问题。示例代码如下:
self
在class MyTest(object):
def __init__(self, x):
self.x = x
def __setattr__(self, name, value):
if name=="device":
print "device test"
else:
setattr(self, name, value)
test = MyTest(1)
代码尝试创建新属性__init__
时,它会调用x
,再次调用__setattr__
,依此类推。如何更改此代码,在这种情况下,会创建__setattr__
的{{1}}新属性,并保留值x
?
或者有没有更好的方法来处理self
之类的呼叫被“映射”到1
?
因为总是存在关于原因的问题:我需要创建instance.device.read
调用的抽象,为此可以创建非常简单的方法,如instance.read
和类似的方法。我需要'模拟'这样来模仿这种多点方法调用。
答案 0 :(得分:45)
您必须调用父类__setattr__
方法:
class MyTest(object):
def __init__(self, x):
self.x = x
def __setattr__(self, name, value):
if name=="device":
print "device test"
else:
super(MyTest, self).__setattr__(name, value)
# in python3+ you can omit the arguments to super:
#super().__setattr__(name, value)
关于最佳做法,因为您打算通过xml-rpc
使用此功能,我认为在_dispatch
方法中可能会做得更好。
快速而肮脏的方法就是:
class My(object):
def __init__(self):
self.device = self
答案 1 :(得分:18)
或者您可以在self.__dict__
内修改__setattr__()
:
class SomeClass(object):
def __setattr__(self, name, value):
print(name, value)
self.__dict__[name] = value
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
sc = SomeClass(attr1=1, attr2=2)
sc.attr1 = 3
答案 2 :(得分:3)
您也可以使用对象。
tf.image.non_max_suppression
答案 3 :(得分:1)
如果您不想指定可以设置或不能设置哪些属性,则可以拆分该类以将get / set挂钩延迟到初始化之后:
class MyTest(object):
def __init__(self, x):
self.x = x
self.__class__ = _MyTestWithHooks
class _MyTestWithHooks(MyTest):
def __setattr__(self, name, value):
...
def __getattr__(self, name):
...
if __name__ == '__main__':
a = MyTest(12)
...
如代码中所述,您将要实例化MyTest,因为实例化_MyTestWithHooks将导致与以前相同的无限递归问题。
答案 4 :(得分:0)
或者您可以只使用@property:
df1 = df[['ma', 'freq1']]
df2 = df[['phd', 'freq2']]
df1.merge(df2, left_on='ma', right_on='phd')
ma freq1 phd freq2
0 a 1 a 8
1 b 2 b 9