Предположим, вы сделали два экземпляра MySystem
:
model1 = MySystem()
model2 = MySystem()
Если бы model1.event.terminal = True
было разрешено, то это также повлияло бы
model2.event.terminal
. Python запрещает устанавливать атрибуты методов
предотвратить это удивительное действие на расстоянии.
Подробнее о том, почему это запрещено, объясняется здесь .
За PEP-0232 (мой акцент):
Невозможно установить
атрибуты в связанных или несвязанных методах , за исключением случаев, когда это делается явно в
базовый объект функции
Можно установить атрибуты метода, используя event1.__dict__['terminal'] = True
но учтите, что это влияет на все экземпляры MySystem
, а не только на один экземпляр model
.
Так как это влияет на MySystem.event
на уровне класса, лучше установить event.terminal
в определении класса,
или с помощью MySystem.event.terminal = True
сразу после определения класса. (Обратите внимание, что MySystem.event
является базовым объектом функции
упоминается в приведенной выше цитате PEP.)
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
class MySystem:
def __init__(self):
self.param = 1
def dynamics(self,t,x):
return (x-self.param)**3-x
def event(self, t, x):
return x
event.terminal = True
# MySystem.event.terminal = True # also works
model = MySystem()
event1 = model.event
# event1.__dict__['terminal'] = True # works, but perhaps confusing because it affects all instances
sol = solve_ivp(model.dynamics, t_span=(0, 1.5), y0=[1], events=event1)
print(sol)
plt.plot(sol['t'], sol['y'][0])
plt.scatter(sol['t_events'][0], [0], c='red')
plt.show()