# we know that any Funtion or any varrible can't be used before assignment like below..........


try:
    printing()
except NameError as nmERR:        # it has thrown an NameERor 
    print(nmERR)	 # that name 'printing' is not defined 🥴

def printing(self):
    print('hello')

try:
    print(varrible)                             
except NameError as vrNmerr:      # similarly, it has thrown an 
    print(vrNmerr)	 # NameError that name 'varrible' is not defined

varrible = 200


# but we can do this inside of Class 😎, I mean we can use any Method or Function or any Varrible
# before assignment inside of Class or OOP 🤩 from inside of any Method (remember this)
# look at below...


class Without_any_reason:

    def __init__(self):
        self.printing_met()
        print(self.varrible)

    def antoerh(self):
        self.printing_met()           
        print(self.varrible)         
        
        
        
# as we can see we can use the 'printing_met()' and 'varrible' before assignment 😁, 
# but remember we should call them from inside any Method
# Otherwise, we can't use them 🤐



    def printing_met(self):
        print('Hey..!')
        self.varrible = 10

obj1 = Without_any_reason()
obj1.antoerh()