Operators are basically used to perform operations on the data to be manipulated. There are various kinds of operators i.e. Logical Operators, Bitwise Operators, Arithmetic Operators, etc.

There are two kinds of AND Operators in Python:

`Logical AND Operator`

`Bitwise AND Operator`

## Logical AND Operator

Logical AND operator work with boolean values and results into True or False based on the condition. The **and** operator returns True when both the operands are True, else it returns False.

**Syntax:**

operand1 and operand2

**Example**:

```
num1 = int(input('Enter first number:\n'))
num2 = int(input('Enter second number:\n'))
if num1 > num2 and num1 < 10:
print('True')
elif num1 < 0 and num2 < 0:
print('Both the numbers are negative.')
else:
print('False')
```

**Output**:

Enter first number:

9

Enter second number:

5

True

## Logical Operator Overloading

Python logical operators work on boolean values. By default, an object boolean value is **True**. If the object is **None** or **False**, then the boolean value is **False**. We can provide **__bool__()** implementation to change the default boolean values of an object.

```
class Data:
def __init__(self, i):
self.id = i
def __bool__(self):
return self.id % 2 == 0
d1 = Data(6)
d2 = Data(4)
print(bool(Data(3)) and bool(Data(4))) # False
```

The above code snippet will print False because Data(3) boolean value is False.

If we remove the __bool__() function implementation, both the Data objects boolean value will be True and it will print True.

## Bitwise AND Operator

Bitwise operators work on bits. It returns 1 when both the bits of the operands is 1 else it returns 0(zero).

**Syntax:**

operand1 & operand2

a = 6 = 0110 (Binary)

b = 4 = 0100 (Binary)

a & b = 0110 & 0100 = 0100 = 4 (Decimal)

**Example**:

```
a = 6
b = 4
c = a & b
print(c)
```

**Output**:

4

## Bitwise Operator Overloading

There are various defined methods to overload Bitwise operators in Python.

Bitwise Operator | Syntax |
---|---|

& | __and__(self, other) |

| | __or__(self, other) |

^ | __xor__(self, other) |

~ | __invert__(self) |

<< | __lshift__(self, other) |

>> | __rshift__(self, other) |

```
class Operate():
def __init__(self, x):
self.x = x
def __and__(self, res):
print("Bitwise AND operator overloading Example")
if isinstance(res, Operate):
return self.x & res.x
else:
raise ValueError("Must belong to Operate Class")
if __name__ == "__main__":
a = Operate(6)
b = Operate(4)
print(a&b)
```

**Output**:

Bitwise AND operator overloading Example

4

## Order of Evaluation of logical operators

The execution of operands through operators happen from `left to right`

.

**Example**:

```
def evaluate(n):
print("Function called for operand:", n)
return True if n > 0 else False
x = evaluate
y = evaluate
z = evaluate
if x(-1) or y(5) and z(10):
print("One of the numbers is positive.")
```

**Output**:

Function called for operand: 5

Function called for operand: 10

One of the numbers is positive.