使用 *args,**kwargs 来管理客户端类中调用的不同对象的 API(面向对象设计)



有一个Python类,比如Environment,它需要调用其他类的方法,比如PedestrianCarPlane。在实践中,我将这些类的实例传递到某个Environment方法中,并且此方法调用传入的对象的方法。PedestrianCarPlane共享一些类似功能的方法,比如get_speed,但get_speed应该根据对象使用不同的输入来调用:例如Pedestrian.get_speed(soil_type)Plane.get_speed(weather_type, air_resistance)Environment中的某个方法调用.get_speed在某个时间点传入的对象。我的问题是我希望这个来自Environment的调用适用于传入的任何对象,所以我需要根据object_passed_in的类型处理不同的输入集来object_passed_in.get_speed。什么是高效/优雅的方式?

我想做什么:

  1. 添加到get_speed方法中,对于所有这些对象,参数*args**kwargs,并且忽略这些对象捕获的任何参数
  2. Environment类中,使用所有可能有用的参数(soil_typeair_resistance、weather_type' 等(调用object_passed_in.get_speed,并丢弃 *args、**kwargs 中捕获的任何参数。

这个解决方案好吗?(对我来说似乎不是很干净(有没有更好的方法?

Environment不应该关心细节。相反,Envioronment方法的调用方应负责传递必要的参数。

class Environment:
# Precondition: argument obj must have a callable 'get_speed' attribute
def foo(self, obj, *args, **kwargs):
...
speed = obj.get_speed(*args, **kwargs)
...

...
e = Evironment()
e.foo(ped, soil_type="dirt")
e.foo(plane, "cloudy", .032)
# etc

可能更好的是,Environment.foo甚至不需要知道正在调用get_speed;相反,它可以调用零参数函数,并且传递的函数负责使用正确的参数调用对象的get_speed方法。如果foo本身需要获取要传递给get_speed的参数以外的参数,这可能会更简单。

from functools import partial

class Environment:
def foo(self, f, x):
speed = f()

e = Environment()
e.foo(partial(ped.get_speed, soil_type="dirt"), 9)
e.foo(partial(plane.get_speed, "cloudy", .032), 6)
# etc

最新更新