The Peculiar Rounding Method
When rounding values exactly at the halfway mark, Python uses banker's rounding. This ties outcomes toward the nearest even digit rather than always moving upward.
print(round(9/2)) # 4
print(round(7/2)) # 4
print(round(3/2)) # 2
Both 3.5 and 4.5 steer toward 4, avoiding cumulative upward bias.
Attribute Rseolution and Dunder Methods
Instance attributes typically shadow class attributes, but dunder (double underscore) methods are resolved differently—they bypass the instance dictionary.
class Demo:
shared = 9
def __init__(self):
self.val = 10
self.__add__ = lambda x, y: x.val + y
def __add__(self, other):
return self.val - other
print(Demo() + 4) # 6
The interpreter ignores the instance-level __add__ and uses the class method, computing 10 - 4.
Comparing Negative and Positive Zero
The max built-in returns the first occurrence when equal values compete.
print(max(-0.0, 0.0)) # -0.0
Since -0.0 and 0.0 are considered equal, the first one encountered wins.
Emptiness in any() and all()
Both predicates treat empty iterables in a lazy manner.
print(all([])) # True
print(any([])) # False
all() looks for a falsy element; finding none, it returns True. any() seeks a truthy element; with none present, it yields False.
Negative Multipliers on Sequences
Multiplying a string by a negative integer produces an empty string.
print("Hello" * (-1)) # ''
Negative multipliers are treated as zero, giving an empty sequence of the same type.
The Type–Object Relationship
type and object are mutually dependent, making every entity an object and every class a type instance.
print(isinstance(object, type)) # True
print(isinstance(type, object)) # True
print(isinstance(type, type)) # True
print(isinstance(object, object)) # True
Sum with Empty Iterables
If the iterable is empty, sum() returns the start value without modification.
print(sum("")) # 0
print(sum("", [])) # []
print(sum("", {})) # {}
Late Binding in Methods
Python does not resolve names inside a function body until it is called.
class Wrapper:
def action(self):
return Wrapper()
instance = Wrapper()
Wrapper = int
print(instance.action()) # 0
During execution, the name Wrapper is rebound to int, so calling action returns int().
Imaginary Parts Across Numeric Types
Every numeric type, including float('inf') and float('nan'), exposes .imag.
items = [0, 5, 10e9, float('inf'), float('nan')]
print(sum(a.imag for a in items)) # 0.0
Integer and Float Precision Collision
Operations mixing large integers with floats can produce misleading comparisons due to floating-point rounding.
value = (1 << 53) + 1 # 9007199254740993
result = value + 1.0
print(result > value) # False
When adding 1.0, the integer is coerced into a float that rounds to 9007199254740992.0, keeping the final float lower than the original integer.