0

I am setting a function where the user can specify how to initialize a variable. Here is a minimal example

def setValue( typeOf ):
    if typeOf == 'normal':
        a = np.random.normal( parameters)
    if typeOf == 'uniform':
        a = np.random.uniform(parameters)

However, in my real case, there are dozens of initialization options. I am wondering if I can make the code more elegant my specifying directly how the user wants to initialize the variable

def setValue( something ):
    something hapenng
    a = np.random.whatever_user_specified
SantoshGupta7
  • 5,607
  • 14
  • 58
  • 116

3 Answers3

3

It is not a question of being pythonic or not, but is rather a question of code design. There are multiple ways to achieve what you want, and your choice mainly depends on the function contract. That said, one approach would be to accept the initializing function as the argument:

def setValue(distribution):
  a = distribution(parameters)

setValue(np.random.normal)

with the use of functools.partial you can fixate parameters of the initializer if necessary

setValue(partial(np.random.normal, scale=1))

A different approach would be to have a static mapping between names and initializers:

distribution = {
  'uniform': np.random.uniform,
  'normal': np.random.normal,
}

def setValue(name):
  a = distribution[name](parameters)

setValue('normal')

Finally, you can always use introspection to call the method indirectly

def setValue(name):
  a = getattr(np.random, name)(parameters)

setValue('uniform')

but this is a subject to code smell and also is not secure if being run in an untrusted environment.

There are other approaches as well, but they are far more complicated and, as I said, mainly depend on the code design.

Alexander Solovets
  • 2,447
  • 15
  • 22
2

Use getattr to fetch a function by name:

method = "uniform"
if method in ["normal", "uniform"]:
    func = getattr(np.random, method)
    func()
# => 0.10683518702441452

You could also be excepting AttributeError, but that might give a bit more access than you meant to give.

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

Maybe you want to use getattr()?

def setValue(typeOf):
    func = getattr(np.random, typeOf)
    a = func(parameters)
wjandrea
  • 28,235
  • 9
  • 60
  • 81