I have an idea for a new special method in a class called __first__(). The main purpose of it would be to setup somethings a class needs to run before it is first initiated, probably only really in modules because in your code you could simply put this setup stuff before the class however if you are calling something like 'from foo import Bar', where Bar is a class and Bar needs some specific imports you would need something to run the first time Bar is initiated. I have two possible ideas for how this could be done. To look at how this is going to work I will make an example class which would be in the class foo: class Bar(object): def __first__(): import math def __init__(self, n): self.a = math.log(2, n)
The first possible way is that if you just call Bar (without brackets or any attributes) this is when it will run __first__ so you can just do this after you run 'from foo import Bar'. However I don't particularly like this idea because you could just create a staticmethod setup or something instead of __first__ and then rather than running Bar you would just run Bar.setup(), not much harder. Personally I prefer my second idea. This is that when you first run Bar.__new__() it will check if it has a __first__() and if so it will run __first__ and then it will run the normal __new__. However, if you then create another instance, so run __new__ again, it will not run __first__ again so it is still an efficient place to run imports or setup of things.
As an example of where this could be useful, I made a module 'temperature' to help me neatly read one-wire temperature sensors with a raspberry pi. This included a class Sensor which you gave the code of the sensor and then when you called temp of that instance it will return what temperature that sensor is reading. I would like in my other code to be able to run 'from temperature import Sensor' because that would then mean I could just call Sensor('28-000648372f') to create a sensor however at the start of this module it imports os and glob and it also runs some setup for how it reads the sensors and has such I have to just do 'import temperature' and then every time I create a sensor I have to call temperature.Sensor which isn't as nice.
I was wondering what you thought of this idea.
The Big Cheese wrote:
however at the start of this module it imports os and glob and it also runs some setup for how it reads the sensors and has such I have to just do 'import temperature' and then every time I create a sensor I have to call temperature.Sensor which isn't as nice.
I think you may be mistaken about how module importing works. Doing 'from temperature import Sensor' still runs all the top-level code in the temperature module, just the same as 'import temperature' does.
So, the feature you're requesting is not necessary. All you have to do is write your setup code as top-level statements in the module where the class is defined.
I forstthpughthgegoal here was to avoid imports that may not be needed if the class isn’t actually used. If that’s the case, then it’s better to simply put classes with heavyweight imports in their own module.
def __first__(): import math 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__:
Import math 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.