glenn said:
lol - actually Im confused about this - there seem to be cases where
instantiaing with:
instance=module.classname()
gives me an error, but
instance=module.classname
doesnt -
These two syntaxes are both legal, but yield different results.
<short>
You *have* to use "instance=module.classname()" to instanciate
module.classname. Else what you get is the class itself, not an instance
of it.
</short>
<longer>
In Python, everything (including modules, classes and functions) is an
object.
The dot ('.') is a 'lookup' operator - 'someobj.someattr' tries to
retrieve attribute 'someattr' from object 'someobj' (according to lookup
rules that are explained in the doc) - whatever that attribute is. So
the expression 'module.classname' yields the attribute 'classname' of
object 'module' (or raise an AttributeError). Execution of the statement
'instance = module.classname' binds the name 'instance' to whatever
expression 'module.classname' yielded - in you case, the class object,
not an instance of it.
Now functions and classes are "callable" objects - which means they
implement the __call__(self, ...) magic method, so you can apply the
call operator to them. Classes are actually callable objects acting as
factory for instances (ie: calling a class object returns an instance of
that class). The expression "someobj.someattr()" *first* lookup for
attribute 'someattr' of object 'someobj', *then* call it.
so I got into that habit, except for where I had a constructor
with parameters
Programming by accident is a well-known antipattern.
- except now Im feeling foolish because I cant
replicate the error - which suggests I didnt understand the error
message properly in the first place...
And that you misunderstood a very important point of Python's syntax.
The call operator (ie parenthesis) is *not* optional.
arrgh
I guess thats just part of the process of gaining a new language.
Probably, yes !-)