【问题标题】:Dynamically Modify Python Method and Arguments动态修改 Python 方法和参数
【发布时间】:2020-07-31 07:20:45
【问题描述】:

我正在使用 Python,我从此处的参数的 REST 端点获取定义:

https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Network/ESRI_DriveTime_US/GPServer/CreateDriveTimePolygons?f=json

我想做的是:

  1. 创建一个名为:CreateDriveTimePolygons 的函数
  2. 添加输入参数
  3. 引用类中可以处理这些输入的函数。
OnlineMethod(above_url).CreateDriveTimePolygons(Input_Location=(25,-34), Drive_Times="5,12,31")

我可以在 obj 上使用setattr 来定义一个预制函数,但我的问题如下:

  1. 如何更改方法的签名名称?
  2. 如何修改方法的输入参数?

谢谢

目标是不使用 kwargs 或 args

【问题讨论】:

标签: python methods dynamic


【解决方案1】:

对于第 2 点,如果通过修改是指传递可变数量的争论/参数,您可以参考此链接:

https://www.geeksforgeeks.org/args-kwargs-python/

如果通过修改您的意思是更改函数中传递的值,那么您可以将值存储在变量中并将这些变量作为参数/参数传递给方法。

【讨论】:

  • 我希望参数是明确的。我知道 kwargs 和 args 参数。让我们简单一点:add(**kwargs) 不像 add(x,y) 那样好用
  • 好的,那么您对参数数量有任何最大限​​制吗?因为如果你这样做了,那么你可以在定义函数时将一些参数设置为默认参数,并在调用函数时传递所需数量的参数
  • 因为我正在包装 Web 服务端点,所以在用户传入 URL 之前,我不知道默认参数是什么。
【解决方案2】:

我想我已经解决了类似的问题。当我从事 API 版本控制

如果用户代理请求在 URL 参数中包含 v1,则初始化 v1 API/管理器类或 v2 等等。

为此,我们可以在适配器模式上使用部分实现,方法是为您的案例中的一组类/方法创建一个映射。

class OnlineMethod(object):
    ...
    def __init__(self, url):
        pass

    def create_drive_time_polygons(self, *args, **kwargs):
        pass

    ...

action_method_map = {
    'CreateDriveTimePolygons': OnlineMethod().create_drive_time_polygons,
}


action_method_map['CreateDriveTimePolygons'](Input_Location=(25,-34), Drive_Times="5,12,31", Output_Drive_Time_Polygons=[1,2,3])


action_method_map[action_from_url](Input_Location, Drive_Times, Output_Drive_Time_Polygons)

这有意义吗?

【讨论】:

    【解决方案3】:

    您始终可以使用锤子固定显微镜evalexec 来动态编写 Python 代码。但在这种情况下,您将有更多责任来防止错误。

    class A:
      def __init__(self):
        pass
    
    A.some_method = lambda self, x: print(x ** 2)
    
    a = A()
    a.some_method(20)  # 400
    
    args = ['x', 'y', 'z']
    A.new_method = eval(f'lambda self, {", ".join(args)}: print(sum([{", ".join(args)}]))')
    a.new_method(1, 2, 3)  # 6
    

    【讨论】:

    • 虽然这看起来像一把锤子,但我可以创建通用的 self._run_method(**kwargs) 或类似的东西。
    【解决方案4】:

    我想你可能想试试 Python 中的 Metaclass。

    https://realpython.com/python-metaclasses/#defining-a-class-dynamically

    【讨论】:

      猜你喜欢
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多