我尝试根据对象创建过程中给出的参数动态定义类中的函数。我尝试了一些想法(下面的代码),但它们都无效。也许这是不可能的。我想这样做是因为我会在蒙特卡罗模拟中经常调用_exec
方法。
我的第一个失败的想法:
class Test_Class_1():
def __init__(self, a = None):
if a:
self.a = a
if hasattr(self, 'a'): #self is undefined.
def _exec(self):
print(self.a)
else:
def _exec():
print('no a')
我的第二个失败的想法:
class Test_Class_2():
def __init__(self, a = None):
if a:
self.a = a
try self.a: #this is invalid syntax
def _exec(self):
print(self.a)
except:
def _exec():
print('no a')
我当然可以创建不同的类来实现这一点,但我更希望一个类具有更易于理解的代码结构(更短)。
感谢您的想法!
答案 0 :(得分:2)
您可以覆盖__setattr__()
方法,根据属性_exec()
的值动态更新a
方法。 _exec()
的两个不同实现作为类中的方法提供,并且每当修改属性时都会选择适当的实现。
如果使用__delattr__
删除属性,也会覆盖del
。
class TestClass:
def __init__(self, a=None):
self.a = a
def _exec_a(self):
print(self.a)
def _exec_no_a(self):
print('no a')
def __setattr__(self, name, value):
# print('__setattr__():', name, value)
super().__setattr__(name, value)
if name == 'a':
if value is not None:
self._exec = self._exec_a
else:
del self.a
def __delattr__(self, name):
# print('__delattr__():', name)
super().__delattr__(name)
if name == 'a':
self._exec = self._exec_no_a
像这样使用:
>>> x = TestClass()
>>> x.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TestClass' object has no attribute 'a'
>>> x._exec()
no a
>>> x.a = 123
>>> x._exec()
123
>>> x.a = 'hello'
>>> x._exec()
hello
>>> x.a = None
>>> x.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TestClass' object has no attribute 'a'
>>> x._exec()
no a
>>> x.a = 500
>>> x._exec()
500
>>> del x.a
>>> x._exec()
no a
>>> x.a = True
>>> x._exec()
True
>>> x = TestClass(a='xyz')
>>> x._exec()
xyz
>>> del x.a
>>> x._exec()
no a
答案 1 :(得分:1)
这样做的一种自然方式是:
class Test_Class_1():
def __init__ (self, a=None):
if a:
self.my_func = lambda y: y*y
m = Test_Class_1()
m.my_func(100) # raises an error because my_func doesn't exist
v = Test_Class_1(100)
v.my_func(100) # returns 10000
您的第一个想法不起作用,因为self
是一个局部变量,仅在执行方法时存在。在执行类主体时,它不存在。
答案 2 :(得分:0)
可以这样做,只需创建一个辅助函数,使用setattr
设置函数:
def set_func(self):
if hasattr(self, 'a'): #self is undefined.
def _exec(self):
print(self.a)
setattr(type(self), '_exec', _exec)
else:
@staticmethod
def _exec():
print('no a')
setattr(type(self), '_exec', _exec)
并在a
中设置__init__
后调用它:
def __init__(self, a = None):
if a:
self.a = a
self.set_func()