Warm tip: This article is reproduced from serverfault.com, please click

Is it possible to parametrize a method being called by dot notation?

发布于 2020-11-28 05:15:46

Just what the title says, I'm trying to figure out if you can parametrize a method being call via dot notation.

def funk(x,a_class_method):
    return [i.a_class_method() for i in x]
    
a_class_method = upper
funk(x,a_class_method)

input

x = ['hi', 'my', 'name', 'is', 'frank']

desired output

['HI', 'MY', 'NAME', 'IS', 'FRANK']

As written this results in

NameError: name 'upper' is not defined

Questioner
will.cass.wrig
Viewed
0
HTNW 2020-11-28 13:42:09

As a general rule, passing around the name of a function is not a good way to think about/do things. Just pass functions:

def funk(x, f):
    return [f(i) for i in x]

funk(['hi', 'my', 'name', 'is', 'frank'], str.upper) # pass the method itself
# str.upper(x) is the same as x.upper() for any str x
# or write
funk(['hi', 'my', 'name', 'is', 'frank'], lambda x: x.upper()) # pass a function that calls the method
# (lambda x: x.upper())(y) is the same as y.upper()
# you could also write the following (but why would you?)
def oneOffFunction(x):
    return x.upper()
funk(['hi', 'my', 'name', 'is', 'frank'], oneOffFunction) # pass another function that calls the method

Using the first form requires you know the type of the objects you're calling the method on. Using the second and third you call the method purely by name, regardless of type. You would rarely want/need the getattr way.

Note that funk(xs, f) is equivalent to list(map(f, xs)).