6

I am using Python, and I get a definition from a REST endpoint of the parameters here:

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

What I want to do is the following:

  1. Create a function called: CreateDriveTimePolygons
  2. Add the input parameters
  3. reference the function within the class that can handle these inputs.
OnlineMethod(above_url).CreateDriveTimePolygons(Input_Location=(25,-34), Drive_Times="5,12,31")

I can use setattr on the obj to define a pre-made function, but my question is the following:

  1. How can I change the signature name of the method?
  2. How can I modify the input parameters of the method?

Thank you

The goal is to not use kwargs or args

JabberJabber
  • 341
  • 2
  • 17
  • Similar question: [Set function signature in Python](https://stackoverflow.com/questions/1409295/set-function-signature-in-python/50533832#50533832). – D Malan Apr 29 '20 at 11:23
  • If you could elaborate more about how you would like your code to look like, and why do you need to dynamically change the arguments it help us understand what is the right approach. – theFrok Apr 30 '20 at 09:31
  • Check this answer to dynamically create a method in class https://stackoverflow.com/a/19693065/7477462. – Premkumar chalmeti Apr 30 '20 at 18:18

4 Answers4

2

You can always use a hammer to fix a microscope eval or exec to dynamically write Python code. But in this case you'll have a lot more responsibility to prevent bugs.

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
nik7
  • 806
  • 3
  • 12
  • 20
1

I think I've solved a similar kind of problem. When I was working on API versioning

like if user agent request contains v1 in URL params then initialize the v1 APIs/ manager classes or v2 and so on.

For this, we can use partial implementation on the adapter pattern by creating a map for a set of classes/methods in your case.

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)

Does that make sense?

Premkumar chalmeti
  • 800
  • 1
  • 8
  • 23
0

For point 2,If by modify you mean passing a variable number of arguements/parameters , you can refer this link :

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

If by modify you mean change the values passed in the function, then you could just store the values in variables and pass those variables as arguements/parameters in the method.

Aryan
  • 21
  • 3
  • I would like the parameters to be explicit. I am aware of the kwargs and args parameters. Let's make it simple: add(**kwargs) is not as easy to use as add(x,y) – JabberJabber Apr 17 '20 at 18:43
  • Okay,so do you have any max limit on the number of parameters? Because if you do then you can just set some as default parameters while defining the function and pass the required number of parameters as and when the function is called – Aryan Apr 18 '20 at 06:30
  • Since I'm wrapping web service endpoints I do not know what the default parameters will be until a user passing in the URL. – JabberJabber Apr 20 '20 at 10:30
0

I think you might want to try Metaclass in Python.

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

Bhushan
  • 2,256
  • 3
  • 22
  • 28