Reputation: 20916
I see the below statement in the github link and would like to how this condition is executed. The right expression to the or checks for a condition but the left side is more of a assigment statement.
shape.fill = shape.selected or shape == self.hShape
Upvotes: 2
Views: 81
Reputation: 366133
You're getting the precedence wrong.1
This is an assignment statement, where the left side is the name shape.fill
, and the right side is the or
expression. It's not an or
statement, where the left side is an assignment and the right side is a comparison.
In other words, it's equivalent to:
shape.fill = (shape.selected or shape == self.hShape)
And to avoid any other confusion, the ==
is evaluated before the or
, so it's ultimately equivalent to this:
shape.fill = (shape.selected or (shape == self.hShape))
And hopefully you understand what that means.
The implicit precedence rules2 for every operator, symbol, and keyword can be inferred by worked out by reading the syntax in the Reference Manual, starting from Top-level components and working down through statements (simple and complex) and expressions. Or you can read the Full Grammar specification for a more concise but less explanatory version.
But since you're using Python, you might prefer to learn by experimentation rather than by manual. In that case, check out the ast
module:
>>> import ast
>>> statement = 'shape.fill = (shape.selected or shape == self.hShape)'
>>> print(ast.dump(ast.parse(statement)), annotate_fields=False)
("Module([Assign([Attribute(Name('shape', Load()), 'fill', Store())], "
"BoolOp(Or(), [Attribute(Name('shape', Load()), 'selected', Load()), "
"Compare(Name('shape', Load()), [Eq()], [Attribute(Name('self', Load()), "
"'hShape', Load())])]))])")
OK, that may be a bit hard to follow, but there are some nice third-party libs that format the tree more clearly. It comes down to this:
Module
Assign
Attribute
Name('shape')
'fill'
BoolOp
Or
Attribute
Name('shape')
'selected'
Compare
Name('shape')
Eq
Attribute
Name('self')
'hShape'
So, you can see that there's an assignment (Assign
) where the left side is the attribution (Attribute
) and the right side is the or
expression (BoolOp
).
1. Technically, there's no precedence going on, because =
isn't even an operator in Python. But it's easier to think about it this way, and only a tiny bit misleading, and hopefully the next sentence clears it up.
2. Again, the only explicit precedence rules are those that apply to operators, which doesn't include the =
in your example. So you have to work out how the statement will be parsed, effectively the same way the parser does.
Upvotes: 3
Reputation: 104852
The or
operator binds less tightly than the =
you see on the left. Adding some parentheses may make the situation clearer:
shape.fill = ((shape.selected) or (shape == self.hShape))
The parentheses I've added don't change anything in how the statement is evaluated. The two arguments to or
are shape.selected
(which is presumably a bool
), and the expression shape == self.hShape
. The result of the or
expression is what gets assigned to shape.fill
.
Upvotes: 2
Reputation: 363566
In this context, shape.selected
is a boolean attribute, so the code is equivalent to this:
if shape.selected:
shape.fill = shape.selected
else:
shape.fill = shape == self.hShape
Does that help?
Upvotes: 3
Reputation: 1682
It is evaluating the same sort of statement you would see in an if
statement.
They are creating a boolean and assigning it to shape.fill
. Presumably, shape.selected
is either True
or False
. They are then applying a logical or
with another boolean statement shape == self.hShape
.
In the end, it is of the form
shape.fill = (boolean variable) or (boolean expression)
while evaluates to a boolean.
Upvotes: 1