On Sun, Jul 14, 2002 at 06:46:59PM +0300, Vladimir Bormotov wrote: > >>>>> "MS" == Michael Stenner <mstenner@xxxxxxxxxxxx> writes: > >> and, please, no import inside functions (look at 'import rpm' in this > >> grep output and many-many-many import string/os/sys/etc in other > >> sources)... > > MS> I'm not going to defend the yum examples specifically, because I > MS> haven't even looked at them, but I feel strongly that this should not > MS> be interpreted as an absolute rule. > > MS> 1) In some cases, the program may not know until runtime if certain > MS> modules will be present. > > MS> An example is a cross-platform program that has a copy_file > MS> function. On windows/unix, you use the copy function from the > MS> shutil module. On a mac, you use the copy function from > MS> macostools. macostools doesn't exist on a linux install, so you > MS> can't just import it at the top of a file. > > I can. example from real crossplatform code (not from yum) > > at top of file: > > if sys.platform == 'cygwin': > print "Cygwin does not grok locales" > print "produced files may have wrong formatting" > elif os.name == 'nt': > locale.setlocale(locale.LC_CTYPE, '.%s' % WIN_CP) The "just" in "you can't just import it" was there specifically for things like this. That's precisely what I do in some cases. But it often happens inside a function, because it's also good design to break up your code into functions. > this is right place to any import, and other platform specific code. > For "fast writed code". For "long-play, code" - platform specific code > must be wrapped, and moved out from main project sources, into modules. > As result, main code import one module at any platform. Small portions of > platform specific code in each module will be more readable. That's _a_reasonable_ way to do it, and I like it. There are other reasonable ways to do it, too. In some cases this will be cleaner and easier to understand. In others, it won't. > MS> Sure, you could try and import the module and catch the exception, > MS> but I think it's cleaner to determine what platform you're on, and > MS> then import the appropriate modules and set up the functions > MS> appropriately. > > of course, try-import-except-import not so good. But, again - yum not in > this case, and local import in specific function no so good too. I said multiple times that I wasn't addressing the specific examples in yum. > MS> 2) Efficiency. If there is a function that needs some heavy modules, > MS> but will rarely be called (ie only when the program is being > MS> invoked in some weird mode), > > ok. at yum sourcetree. > > grep import *py > > Look inside. Any heavy modules? Just say, which module we can classify > as "heavy module". again... not talking about yum specifically. > MS> then it may make sense to import from within that function. > > "function".. Why function? Python is an Object-Oriented language. > No functions. Classes ;) Python is object oriented so that you can use OOP _when_appropriate_. OOP does not make _all_ problems easier and clearer, no matter what the pointy-haired-bosses think. > MS> This way, the modules are never loaded if they're not needed. This > MS> is similar to Just In Time interpretation in a number of ways. > > If we see some "rarely called" function, we see "poor programm design". > This function must be moved into separate class. Class moved into module, > and "heavy module" import once here. At top ;) It is not at all poor program design to have a rarely called function. Imagine a web browser. Along with all of the other stuff that browsers do, this one imports bookmarks & settings from all of the other proprietary formats that the other browsers use. You do that VERY RARELY. Why should we load the code that does that EVERY time we run the browser? How do you propose we decide whether to import it at the top? We can wrap it in if statements, I guess, but we don't know at program startup if we want to import the bookmarks. And wait, this is written in a standard toolkit like gtk, so everything is done from callbacks, which are _functions_. Uh oh. MAYBE you can come up with some convoluted way to do this without putting the import in a function, but it seems really obvious that the cleanest and most readable way to do this is to put the import at the top of the import_bookmarks callback function. def import_bookmarks() import ImportTools ImportTools.import_bookmarks() > MS> Python is very good about efficiently dealing with re-imports (it > MS> doesn't just import it again) so function/class level imports have > MS> little cost except readability. > > readability - big cost. Human resources - very big cost. > > MS> Even there, it sometimes ADDS readability in that it says "most of > MS> this module doesn't use string and re, just this function/class does". > > No. If "rarely called" function not moved out from module, we have "poor > programm design". I disagree with this entirely. But lets say I agree for a moment. You put the function in another module. How do you call the function without IMPORTING that module? This issue is addressed above. > Readabilty of "poor designed programm" not interested. > Who whant read poor designed programm? Who want use programm, with poor > design? Let me get this straight: putting imports in functions is bad design because it normally hurts readability. But in those special cases where it actually helps readability, you don't care because it's poor program design? Why was it poor design again? -Michael -- Michael Stenner Office Phone: 919-660-2513 Duke University, Dept. of Physics mstenner@xxxxxxxxxxxx Box 90305, Durham N.C. 27708-0305