

# A class method is useful when you need a method that involves the class 
# but isn’t instance-specific.
#
# For example:
#
#     you can create an alternative initializer method for a class 
#     by using a class method.
#
# To create a class method in Python, decorate it with @classmethod.

# Let’s say you have a Weight class that instantiates weight objects with kilos:

class Weight:
    def __init__(self, kilos):
        self.kilos = kilos

# You can create Weight objects like this:

w1 = Weight(100)
print(w1.kilos)

# But if you want to create a Weight object from pounds, 
# you have to take care of converting pounds to kilos in advance.

pounds = 220.5
kilos = pounds / 2.205

w2 = Weight(kilos)
print(w2.kilos)

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# So you always need to remember to convert pounds to kilos before 
# creating a Weight. 
#
# This is bad practice.
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

# To solve this probme, let’s create a class method from_pounds() 
# that acts as an alternative constructor or a second initializer:

class Weight:
    def __init__(self, kilos):		# self is reserved param for object
        self.kilos = kilos
    
    @classmethod
    def from_pounds(cls, pounds):	# cls is a reserved param for className
        # convert pounds to kilos
        kilos = pounds / 2.205

        # cls WILL BE the same as Weight. 
	# So: calling cls(kilos) is the same as Weight(kilos)
        return cls(kilos)

# Now we can use:

w1 = Weight(100)
print(w1.kilos)

w2 = Weight.from_pounds(220.5)		# Calls Weight.from_pound
					# which calles: Weight(arg/220.5)
print(w2.kilos)

