
On Fri, Dec 27, 2013 at 01:57:02AM +0000, Amber Yust wrote:
It's a fairly standard pattern to see things like this:
try: import foo except ImportError: foo = None
(and of course, variants with from...import et cetera). These can potentially add a lot of clutter to the imports section of a file, given that it requires 4 lines to do a conditional import.
You can reduce that down to two lines: try: import foo except ImportError: foo = None but your point is taken. A more common pattern in my experience is: try: import this except ImportError: import that as this
It seems like it'd be useful and clean to have a syntax that looked like this:
maybe import foo from bar maybe import baz from qux maybe import quy as quz
Where the behavior would essentially be as above - attempt to run the import normally, and in cases where the import fails, map the name to a value of None instead. Users who want a different behavior are still free to use the long-form syntax.
Hmmm. The basic idea makes a certain level of sense to me, but I'm not sure it makes enough sense to overcome the barrier required before adding a new keyword. I'm not (yet) convinced of the need for this functionality, but if Python did gain this, I think I would prefer the colour of this bike-shed to be "perhaps import" rather than "maybe import". A couple of reasons: - it seems to me that "maybe" is more likely to already be used in code than "perhaps", e.g. in three-value logics (true, false, maybe); - to me, "maybe" feels somewhat random, arbitrary or indeterminant, whereas "perhaps" feels subtly more determinant. I can't justify this claim by dictionary definitions, perhaps it's just me :-) If we're entertaining changes to imports, another possibility would be to allow fallback module names: import this or that or another as this Each of "this", "that", "another" will be attempted, the first successful import being bound to the name "this". The "as this" part would be mandatory, so as to require a consistent name regardless of which module was imported. This would be a syntax error, since it isn't clear what name would be bound at the end: import this or that or another This would also be allowed: from this or that or another import spam With this syntax, we could add None as a special case: import this or that or another or None as this would be equivalent to: module_names = ("this", "that", "another", "None") for name in module_names: if name == "None": spam = None else: try: this = __import__(name) except ImportError: continue break else: raise ImportError and the "from...import" case could be written as: from this or that or None import spam roughly equivalent to: module_names = ("this", "that", "another", "None") for name in module_names: if name == "None": spam = None else: try: temp = __import__(name) spam = temp.spam except ImportError: continue break else: raise ImportError Advantages: - covers both use-cases where you want to try a series of modules, and the one where you fall back to None; - "or" is already a keyword, no new keywords needed; - reads more like English; - "import None" currently gives SyntaxError, so this can't interfere with modules actually called "None". Disadvantages: - more complexity to imports; - only saves a few lines; - this usage of "or" is not quite the same as the usage as a boolean operator, e.g. different from "x in a or b".
A possibly variant might be to also only run the import if the name isn't already bound, so that you could do something like...
from frobber_a maybe import frob as frobber from frobbler_b maybe import frobble as frobber from frobber_c maybe import frobit as frobber
...to potentially try different fallback options if the first choice for an interface provider isn't available.
I dislike this form, because it requires short-circuiting execution of separate lines. What would you expect this to do? from frobber_a maybe import frob as frobber frobber = 23 from frobbler_b maybe import frobble as frobber Is the second maybe import attempted or not? I have no idea whether it should be or shouldn't be. -- Steven