I understand this is the correct way to include a function inside a class, but feels overly complicated and awkward to have to rename existing functions:

from numpy import sin, cos, tan class Foo1: def my_sin(self, x): return sin(x) def my_cos(self, x): return cos(x) def my_tan(self, x): return tan(x) a1 = Foo1() print(a1.my_sin(2)) print(a1.my_cos(2)) print(a1.my_tan(2))

In contrast, this works just as well, and feels neater.

class Foo2: from numpy import sin, cos, tan a2 = Foo2() print(a2.sin(2)) print(a2.cos(2)) print(a2.tan(2))

Why is this wrong, assuming I will only use those functions inside this class? Why does it even work?

(I’ve redacted my example heavily from my original text to keep it focused.)

## Answer

It’s important to put all your imports at the top of the file so someone else or future-you can immediately see your file’s dependencies. Your import statement in `Foo2`

basically adds a module to `sys.modules`

and assigns a few functions to class attributes. We can make class attributes like this:

import numpy as np ## other code that can bury Foo3 deeper into file class Foo3: sin, cos, tan = np.sin, np.cos, np.tan

Has a repetition compared to the import, but it’s still more concise than making forwarding methods like in `Foo1`

. If you planned on renaming the functions, then the repetition would be necessary anyway: `from numpy import sin as s, cos as c, tan as t`

vs `s, c, t = np.sin, np.cos, np.tan`

.

P.S. The other posts linked in comments and answers say that modules are almost always better than classes for putting static method-like functions in namespaces (and they are right), but maybe you want this class to have this class attribute so you can override in subclasses and play with duck-typing.