提问人:Gowzahr 提问时间:8/29/2023 更新时间:8/30/2023 访问量:33
在 python 中定义要在多个类中使用的函数
Define a function to be used in multiple classes in python
问:
是否可以定义一个可以用作多个类一部分的函数?
我首先尝试了这个:
class solvers:
def Euler(self):
self.N += self.dNdt(N) * self.dt
class blob:
# contents of blob go here
methods = solvers()
blob1 = blob()
blob1.solver = methods.Euler
但这只会从方法内部调用 Euler 的别名,留下 blob1。N 不变。 我也试过了
from copy import deepcopy
blob1.solver = deepcopy(methods.Euler)
但这种方法似乎没有改变方法或 blob1 中的 N。
答:
0赞
Reedinationer
8/29/2023
#1
为什么不直接将求解器作为参数传递给 blob 对象呢?我会将代码结构为一个类,其中包含要实现的所有求解器的通用方法,然后可以从该类继承。最后,可以创建所需求解器的实例,并将其传递给 blob 类,如下所示:Solver
Euler
class Solver:
def __init__(self):
self.N = 0
# Add other generic solver methods here
class Euler(Solver): # Note that we inherit from Solver
def __init__():
super().__init__() # Tells python to add all generic solver methods to this
def Euler(self):
self.N += self.dNdt(N) * self.dt
class blob:
def __init__(self, solver):
self.solver = solver
def blah():
self.solver.N = 0 # We can access N like this
# contents of blob go here
blob1 = blob(solver=Euler())
blob1.solver.N = 0 # We can access N like this
现在您可以从内部访问。self.solver.N
blob
除非你说你打算在实例之间共享?不过,像这样共享集成步骤变量似乎是不正确的。self.N
编辑
我们可以将 blob 实例的参数传递给求解器的 init 函数,以在它们之间共享信息,根据您的注释,这似乎是您的目标
import abc
from abc import ABC
class Solver(ABC): # Inheriting from ABC means this is just a template class
def __init__(self, some_n):
self.N = some_n # Every Solver instance will be provided with an N variable at initialization
self.dt = .01 # Every Solver can use this as a time step
@abc.abstractmethod
def iteration_step(self):
pass
class Euler(Solver): # Note that we inherit from Solver
def __init__(self, some_n): # The Euler solver will take the N argument, solely to pass to the initialization on the next line
super().__init__(some_n) # Now the Euler has a self.N property, as well as all other Solver methods
def iteration_step(self):
self.N += self.dNdt() * self.dt # I don't think N needs to be supplied to self.DnDt() because that method can use self.N
print(self.N)
def dNdt(self):
return self.N * 0.05
class blob:
def __init__(self, solver_class: Solver, n_of_blob):
self.solver = solver_class(n_of_blob) # initialize the solver class
def run(self):
for x in range(100):
self.solver.iteration_step()
blob1 = blob(solver_class=Euler, n_of_blob=1.0) # Note that we remove parenthesis from Euler() so that we can make the instance of solver in blob.__init__()
blob1.run()
print("-" * 80)
for x in range(100):
blob1.solver.iteration_step()
请注意,如果运行此示例,则会在输出中看到类似
1.051257959948049
--------------------------------------------------------------------------------
1.051783588928023
这是从使用方法到使用方法的过渡,表明变量在两个作用域中都可以访问blob1.run()
blob1.solver.iteration_step()
评论
0赞
Gowzahr
8/29/2023
问题是 N 是 blob 的一个属性,需要由属于 blob 的其他函数访问(我想使用与求解器相同的方法定义它)。现在我认识到我可以传递 blob。N 到需要它的功能,但这并不像我想要实现的那样干净。
0赞
Reedinationer
8/30/2023
@Gowzahr请看我的编辑
0赞
Gowzahr
8/29/2023
#2
我发现符合我尝试执行的操作的解决方案如下所示:
def Euler(self):
self.N += self.dNdt(N) * self.dt
class blob:
def euler(self):
Euler(self)
这允许诸如
blob.euler()
blob.solve = blob.euler
blob.solve()
评论
blob1.solver = solvers.solver