PyWart: Module access syntax
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sat Jan 12 01:45:03 EST 2013
On Fri, 11 Jan 2013 20:34:20 -0800, Rick Johnson wrote:
>> > import lib:gui:tkinter:dialogs.SimpleDialog as Blah
>>
>> Which names are packages, modules, classes, methods, functions, or
>> other objects?
>>
>> Why do you have lib:gui but dialogs.SimpleDialog? Is the rule "classes
>> should always be preceded by a dot?"
>
> No the rules are:
> * "Colon" must be used to access a "module" (or a package).
> * "Dot" must be used to access a "module member".
So what do you do for, say, os.path? According to the first rule, you
must write it as os:path because path is a module; according to the
second rule, you must write it as os.path because path is a member of os.
So which rule wins?
If I do this:
import math
import string
math.string = string
is that legal, or do I have to write "math:string = string"?
Suppose I do this:
import random
if random.random() < 0.5:
math.string = "NOBODY expects the Spanish Inquisition!"
else:
math.string = string # assuming this actually is allowed
How do I access the string member?
try:
print math.string # only works if string is a str object
except SomeException:
print math:string # only works if string is a module object
That would suck *and* blow at the same time. I don't need to know the
type of any other member object in order to look it up, why should I have
to care whether it is a module?
Now, suppose I then do this:
class Blob: pass
blob = Blob()
blob.math = math # or should that be blob:math ?
Now do I have to write this?
blob.math:string.letters
(assuming that math:string is a module, not a str object).
[...]
> It's simple: MODULES&PACKAGES use colon, MODULE MEMBERS use dot. How
> many times must i explain these simple rules?
At the time I asked the question, you hadn't explained it *at all*.
[...]
> This syntax does not help the programmer much. Well, it can be
> beneficial to the programmer if he gets a *PathError* because he
> foolishly tried to instance a module named "simpledialog" when he
> actually meant to instance the object "simpledialog.SimpleDialog".
> (notice i did not use the word class!)
"Instance" is a noun. The verb you are looking for is "instantiate".
> Traceback (most recent call last):
> File "<blah>", line 1, in <module>
> dlg = lib:gui:tkinter:dialogs.simpledialog()
> PathError: name 'simpledialog' is a module NOT a object!
Of course it is an object. *Everything* in Python is an object. Modules
are objects. Strings are objects. Types and classes are objects. None is
an object. Metaclasses are objects. Properties are objects. Exceptions
are objects. Have I made it clear yet?
[...]
> *The problem:*
> ... is readability. The current dot syntax used ubiquitously in paths is
> not conveying the proper information to the reader, and in-fact
> obfuscating the code.
So you say. I think you are caring too much about the type of members and
not enough about what interface they provide. Why do you care if I grab
module.my_singleton_object and replace my_singleton_object with a module?
Modules are singletons in Python, in the sense that every[1] time you
import a module you get the same object. Using modules as members for
their singleton properties, not for their importability, is a common
technique. With your proposal, I need to know whether a member is a
module, or any other type, before I can access it. That is a really
shitty design. Instead of having one syntax for *all* attribute access,
now you have two, and we have to care whether a member is a module or
not, which we never did before.
Worse, you couple the syntax to implementation: if I use a module as a
singleton, I need to use one syntax; if I use a custom type as a
singleton, I have to use different syntax. Whichever choice I make
*today*, if the implementation changes, the required syntax changes and
my code will break.
[1] Well, almost. There are ways to accidentally or deliberately confuse
the import machinery.
--
Steven
More information about the Python-list
mailing list