1

I am writing a python object class. I just realised that a bunch of my functions are in UK English instead of US English and I need to make sure others on my team can use it.

I was wondering if I can set multiple names for one function so people familiar with both versions of English can use the product.

For example:

def analyse(a, b, c):
    pass

def analyze(a,b,c):
    return alalyse(a, b, c)
rishyak
  • 13
  • 4
  • 5
    `analyze = analyse` somewhere in code – Olvin Roght Aug 03 '21 at 19:59
  • A `def` statement is just a fancy assignment statement. It defines an otherwise anonymous `function` object, then binds a name to that object. You can bind other names to the same object at will. – chepner Aug 03 '21 at 20:01
  • 3
    Ideally, you should just have one name for a function, to avoid confusion. That means your team should have some style guide that tells the team whether function names should be in US English or UK English (or some other variant). That is better than having multiple spellings of an identical function. – 9769953 Aug 03 '21 at 20:03
  • I would say maybe don't do this. Duplicating ways to call one function will probably lead to more headaches than not. If you want to do _something_ though maybe give a custom error message with a [module-level `__getattr__`](https://stackoverflow.com/questions/2447353/getattr-on-a-module). – Kyle Parsons Aug 03 '21 at 20:04
  • You might want to consider other languages as well: French, Spanish, German or even Chinese, Python supports Unicode names. No, frankly, don't waste your time on such details! – Klaus D. Aug 03 '21 at 20:41

5 Answers5

1

Functions can be set to local variables as well:

def foo(x):
  return x

bar = foo

bar(5) == 5

Though I'm personally a fan of aliasing when it can notably improve expressiveness & readability, alternative opinions point to The Zen of Python:

There should be one-- and preferably only one --obvious way to do it.

Your bar for "notable improvement of expressiveness" should be quite high, as aliases hinder findability & traceability, and can subvert expectations. End-user localization is ideally decoupled from app logic specifically to address that kind of problem.

As a developer, I already have to spend a lot of time learning the non-programming, business-domain related concepts pertinent to what I'm building. I wouldn't mind at all to adopt slight variations of British/American/whatever language in return for unambiguous code.

Kache
  • 15,647
  • 12
  • 51
  • 79
1

All answers are right but I prefer an approach where the user understands the "problem":

import warnings

def analyse(a, b, c):
    pass

def analyze(*args, **kwds):
    """Use 'analyse' and not 'analyze'."""
    warnings.warn(analyze.__doc__)
    return analyse(*args, *kwds)
>>> analyze(1, 2, 3)
<ipython-input-125-fcac1ea67ac0>:5: UserWarning: Use 'analyse' and not 'analyze'.
  warnings.warn(analyze.__doc__)
>>> help(analyze)
Help on function analyze in module __main__:

analyze(*args, **kwds)
    Use 'analyse' and not 'analyze'.

With analyze = analyse

>>> help(analyze)
Help on function analyse in module __main__:

analyse(a, b, c)
#    ^ ???
Corralien
  • 109,409
  • 8
  • 28
  • 52
0

In Python everything is an object, so you can just assign the function to a variable which will create a named reference for the function object:

def analyse(a, b, c):
    pass

analyze = analyse
analyze(1,2,3)
ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
0

As functions are first-class objects, you can assign names to them like any other object.

>>> def analyse(a, b, c):
...     print("analysis complete")
...
>>> analyze = analyse
>>> analyze(1,2,3)
analysis complete

A def statement itself is a fancy assignment statement. It defines an otherwise anonymous object, then binds a name to that object.

As far as Python is concerned, there's no difference between the names analyze and analyse: both refer to the same object, and neither one is considered the "real" name. (The fact that analyze.__name__ is "analyse" is a side effect of the def statement, nothing more. The __name__ attribute is metadata that is independent of any name referring to the object, and can be changed at will.)

chepner
  • 497,756
  • 71
  • 530
  • 681
0

You can also use a decorator!

import functools

def alias(alias_f):
    def _(_):
        @functools.wraps(alias_f)
        def _(*args, **kwargs):
            return alias_f(*args, **kwargs)
        return _
    return _

Then use it like that:

def analyze(x):
    return f"Analyzing {x}"
    
@alias(analyze)
def analyse(x): 
    pass

print(analyze(42))    # Outputs Analyzing 42
print(analyse(42))    # Outputs Analyzing 42
enzo
  • 9,861
  • 3
  • 15
  • 38