#oop_county.py #Class is a template, pattern, blueprint, i.e. a data type. #Object is an actual instance of a class, ie. an instantiated variable of a class. #Class/object has members: methods and data/attributes. #Members can be public or private. #Usually the data is private and the methods are public. #Public methods are the interface, the "messages" sent to the object. #Private data members are hidden, inaccessible to client code. __ makes it private. #The object "encapsulates" the data. #Each object has its own set of data members and conceptually its own set of methods. # . operator to access public members. #The methods process the data. They do so correctly and securely. #Client code not trustworthy enough to access the data, nor should it be #burdened to have to do so. Also, implementation changes won't affect client code. #Object knows how to process itself. class County: #capitalize the class name __number_counties = 0 #class variable, one per class. dunder to make it private #constructor (ctor) called automatically for each instantiation def __init__(self, name,state,pop,area): #instance is implicit 1st arg, conventionally named self self.__name = name #instance variables / attributes. __ makes it private self.__state = state #they are visivle to all (non-class) methods self.__pop = pop self.__area = area County.__number_counties += 1 #access a class variable #********** accessor methods *************** #"getter"/"accessor"/"observer" method to safely access private instance variable or some property of the object. def get_name(self): #(instance) method. instance is implicit 1st arg return self.__name def get_state(self): return self.__state def get_pop(self): return self.__pop def get_area(self): return self.__area #********** mutator methods *************** #"setter"/"mutator" method is one that (safely, reliably) changes the object. def change_pop(self,pop_delta): if self.__pop + pop_delta >= 0: #doesn't make it negative... self.__pop += pop_delta #called wherever a str is expected, def __repr__(self): #return a string in format that can be used to create an object return 'County('+self.__name+', '+self.__state+', '+str(self.__pop)+', '+str(self.__area)+')' def __add__(self,other): # self + other return self.__pop + other.__pop def __len__(self): return len(self.__name) #bad example... maybe no natural use of a len @classmethod #decorator to make this a class method. class is implicit 1st arg def count(cls): #typically for accessing class variables return cls.__number_counties @classmethod def decr_count(cls,amount=1): cls.__number_counties -= amount @classmethod def from_string(cls,county_string): #alternative ctor name,state,pop,area = county_string.split(',') return cls(name,state,int(pop),float(area)) @staticmethod #a method logically related to this class. def county_staticmethod1(a,b): #no cls or self arguments, no class or instance variables. return a+b #useless example... c1 = County("Woodruff",'AR',7100,586.79) #instantiate an object. ctor __init__ called. c2 = County("Graham",'AZ',37416,4622.6) #print(c1.__name) #no access to a private instance variable print(c1.get_name()) #getter method called to safely access an encapsulated value c1.change_pop(1000) #setter method called to safely change an encapsulated value print("new pop:",c1.get_pop()) print(c1) # the __repr__ used, otherwise is a memory pointer print(repr(c1)) # __repr__ too print(str(c1)) #if no __str__, the __repr__ is used print(c1.__dict__) #dictionary format #print(c1.density()) #method called #print(County.density(c1)) #or via the class, pass the instance print("class method:",County.count()) #use a class method to access a class variable del c2 County.decr_count() #call a class method print(County.count()) c3 = County.from_string("Yell,AR,21932,929.98") #use the alternative ctor print(c3) print("staticmethod:",County.county_staticmethod1(4,12)) print(type(c3)) print("isinstance:",isinstance(c3,County)) print("plus:",c3 + c1) #__add__ lhs is self, rhs is other print("len:",len(c3)) #__len__ #c3.asdf=123 #gross, can add attributes on-the-fly??? ''' 5147,Woodruff,AR,7100,19167,27047,586.79 5149,Yell,AR,21932,17367,37477,929.98 4007,Gila,AZ,53144,20098,37905,4757.93 4009,Graham,AZ,37416,16116,43083,4622.6 12125,Union,FL,15212,14210,45645,243.56 12127,Volusia,FL,496950,24536,44169,1101.03 12129,Wakulla,FL,30818,22089,54151,606.42 '''