def __init__(self, n):
self.a = math.log(2, n)
This would bring “math” into the __first__ function’s local namespace, and it would not be accessible in other methods anyway.
You could put that import line in __init__, or, if needed in other methods, in __init__:
self.math = math
Then it wouldn’t get imported until the first instance was created.
But this is generally not considered good style.
I have, occasionally, imported heavy weight modules in optional, rarely used, methods so that they aren’t imported (or even need to be there) if they aren’t needed.