It’s not so commonly used in data science, but as an OOP language, Python can make good use of class, object. Unique to Python, there are staticmethod, classmethod, property written by professional programmers.
In short, a staticmethod is a method that knows nothing about the class or instance it was called on, while a classmethod provides a way to creation a function like constructor __init__. For example, in the below class of person, classmethod allows to create a person object by calling Person.fromBirthYear(parameters), while staticmethod is independent without feeding any self settings.
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# a class method to create a Person object by birth year.
@classmethod
def fromBirthYear(cls, name, year):
return cls(name, date.today().year - year)
# a static method to check if a Person is adult or not.
@staticmethod
def isAdult(age):
return age > 18
person1 = Person('mayank', 21)
person2 = Person.fromBirthYear('mayank', 1996)
print person1.age
print person2.age
Another example here:
class RomanNumeral:
SYMBOLS = {'M':1000, 'D':500, 'C':100, 'L':50, 'X':10, 'V':5}
def __init__(self, number):
self.value = number
@classmethod
def from_string(cls, string):
return cls(roman_to_int(string))
@staticmethod
def roman_to_int(numeral):
total = 0
for symbol, next_symbol in zip_longest(numeral, numeral[1:]):
value = RomanNumeral.SYMBOLS[symbol]
next_value = RomanNumeral.SYMBOLS.get(next_symbol, 0)
if value < next_value:
value = -value
total += value
return total
On the other hand, there is a problem in class object that it is needed to change the setting of certain attributes arbitrarily. One way of doing it is to use @property and then setter. For example, below __population is particularly set to be private, and then population attribute can be changed.
class Golem:
__population = 0
__life_span = 10
def __init__(self, name=None):
self.name = name
self.built_year = datetime.date.today().year
self.__active = True
Golem.__population += 1
def say_hi(self):
print('Hi!')
def cease(self):
self.__active = False
Golem.__population -= 1
def is_active(self):
if datetime.date.today().year - self.built_year >= Golem.__life_span:
self.cease
return self.__active
@property
def population(self):
return Golem.__population
@population.setter
def population(self, value):
Golem.__population = value
g = Golem('Clay')
g.population
to quickly set the attr use:
setattr(Golem, ‘population’, 100)
Using Raymond H.’s example of a lean start up creating an MVP (minimal viable product) who specialized in circles, the following is the complete codes
import math
class Circle(object) : # new-style class
'An advanced circle analytic toolkit'
# flyweight design pattern suppresses
# the instance dictionary
__slots__ = ['diameter']
version = '0.7'
def __init__(self, radius):
self.radius = radius # instance variable
@property # convert dotted access to method calls
def radius(self):
'Radius of circle'
return self.diameter / 2.0
@radius.setter
def radius(self, radius):
self.diameter = radius * 2.0
@staticmethod # attach function to classes
def angle_to_grade(self, angle) :
'Convert angle in degree to a percentage grade'
return math.tan(math.radians(angle)) * 100.0
def area(self) :
'perform quadrature on a shape of uniform radius'
p = self.__perimeter()
r = p / math.pi / 2.0
return math.pi * r ** 2.0
def perimeter(self):
return 2.0 * math.pi * self.radius
__perimeter = perimeter
@classmethod #alternative constructor
def from_bbd(cls, bbd) :
'Construct a circle from a bounding box diagonal'
radius = bbd / 2.0 / math.sqrt(2.0)
return Circle(radius)
class Tire(Circle) :
'Tires are circles with a corrected perimeter'
def perimeter(self) :
'Circumference corrected for the rubber'
return Circle.perimeter(self) * 1.25
from random import random, seed
seed(8675309)
print('Using Circuituous (tm) version', Circle.version)
n = 10
circles = [Circle(random()) for i in range(n)]
print('The average area of', n, 'random circles')
avg = sum([c.area() for c in circles]) / n
print('is %.if') %avg
#subclass concept
#constructor war get their wish, dig in their position
#need alternative constructor, the technique is classmethod
To summarize, the tookset is
