CannotChainAttributeAccessesObserved

Attribute accesses cannot be chained together
Attribute accesses can be chained together
CorrectionHere is what's right.
class C:
def work(self):
pass
def m():
return C()
The following two code snippets both invoke a function m()
and then invoke the method work()
on the object returned by m()
:
o = m()
o.work()
m().work()
Here we see the corresponding expressions trees (first example on the left, second one on the right):
The expression m()
evaluates to an object of type C
, and it is perfectly legal to invoke a method on that object.
It’s equally valid to access any attribute on such an object:
m().attr = 19
This writes 19
to the attr
attribute of the object returned by m()
.
OriginWhere could this misconception come from?
Students may believe that there cannot be a non-atomic expression on the left side of the dot. They may have encountered attribute accesses and method invocations in only a limited number of forms, such as:
variable.attr = 19
self.attr = 19
variable.method()
self.method()
SymptomsHow do you know your students might have this misconception?
Students only use atomic expressions on the left side of the dot in attribute accesses and method invocations. If necessary, they break down more complex expressions into multiple statements, each with a single atomic expression on the left side of the dot.
They may always write code like:
o2 = o1.attr
o2.m()
even when o2
is not needed elsewhere, instead of chaining the attribute access and method invocation together:
o1.attr.m()