day06-codes and exercise in class
# Author: Ghost # Email: jiaci.liu@gmail.com ''' 1-Review of last week 2-interface class, abstract class 3-packing 4-special methods classmethod staticmethod property 5-reflection ****************** __hasattr__ __getattr__ __setattr__ __delattr__ 6-advanced special methods __call__ __new__ __getitem__ __setitem__ __delitem__ 7-time, random, ''' ''' Review: combination ''' # class A: # name = 'alex' # def __init__(self, name1, age1): # self.name1 = name1 # self.age1 = age1 # # def func(self): # print(self.name1) # print(self.name) # # def func1(self): # print(self.age1) # # class B: # name2 = 'xiaobai' # def func3(self): # print('in func3') # # obj = A('isa', 24) # objB = B() # # obj.new = objB # print(obj.new.name2) # class A: # n1 = '太白' # # def __init__(self, name1, age1): # self.name = name1 # self.age = age1 # # def func(self): # print(self.name) # self.func1() # print(self.n1) # print(666) # # def func1(self): # print(777) # # obj = A('alex', 73) # # obj.func() # # class B: # n2 = 'WuSir' # # def func3(self): # print('in func3') # # b1 = B() # obj.b = b1 # 组合 给对象新添加了一个属性'b' # print(obj.b.n2) # print(obj.__dict__) ''' single inheritage ''' # class A: # name = 'alex' # # def func(self): # print('IN A') # # # class B(A): # name = '太白' # # def func(self): # # 下面两种表示方法作用相同: # # A.func(self) # # super().func() # # super放前面则先执行A中的function, super放后面则先执行B中的 # print('IN b') # super().func() # # # obj = B() # print(obj.name) # obj.func() # 1. seek for 'name/obj' in current class first, # if 'name/obj' exists, then execute, otherwise parent class will be checked # 2. if attributes of parent class require to be inherited, # attributes with exact names should not be defined in current class ''' execution sequence of dynamic and static attributes (functions) 1. seek for __init__() and execute it 2. seek for destination function in current object-->current class of the object-->parent class ''' # class Parent: # def func(self): # print('in Parent func') # # def __init__(self): # self.func() # # class Son(Parent): # def func(self): # print('in Son func') # # son1 = Son() # class Parent: # def func(self): # print(self.name) # print('parent') # # def __init__(self, name): # self.name = name # # class SON(Parent): # def func(self): # print('son') # obj = SON('xiaobai') # obj.func() ''' Interview questions: 1. attributes assignment inside of functions of a class cannot be referenced, eg.:c, t; 2. corresponding attributes of class cannot be reassigned if they were only reassigned in object; ''' # class A: # a = 0 # b = 1 # def __init__(self): # c = 222 # # def func(self): # t = 444 # # d = A() # d.a = 'new a' # d.b = 'new b' # d.c = 'new c' # print(d.__dict__) # print(A.__dict__) # c, t are not inside of the dict of Class A # # print(A.c) # AttributeError: type object 'A' has no attribute 'c' # print(A.t) # AttributeError: type object 'A' has no attribute 'c' ''' interface class ''' # from abc import ABCMeta, abstractmethod # class Pay(metaclass=ABCMeta): # @abstractmethod # def pay(self, money): # pass # # class AliPay(Pay): # def pay(self, money): # print('alipay %s' % money) # # class wechat(Pay): # def pay(self, money): # print('wechat %s' % money) # # class QQpay(Pay): # def qqpay(self, money): # print('qqpay %s' % money) # # obj = QQpay() # obj.qqpay(11) # TypeError: Can't instantiate abstract class QQpay with abstract methods pay ''' packing of class: # 私有成员:私有变量,私有对象属性,私有方法 # 私有成员:类外面不可以访问,派生类不可以访问,类内面可以访问 ''' # class A: # normattr = 'this is a normal attribute' # __name = 'this is a private attribute' # # def __init__(self, name, item): # self.name = name # normal object attribute # self.__privateattr = item # private object attribute # # def func1(self): # print('this is a normal function') # self.__privatefunc() # # def __privatefunc(self): # print(self.__name) # print('this is a private object function') # # @property # def func2(self): # pass # # @staticmethod # def func3(): # pass # # @classmethod # def func4(cls): # pass # # class AA(A): # pass # # obj = A('parent class', 12) # # obj.__privatefunc() # AttributeError: type object 'A' has no attribute '__privatefunc' # # obj.__name # AttributeError: 'A' object has no attribute '__name' # # obj.func1() # # son = AA('son class', 12) # # son.__name # AttributeError: 'AA' object has no attribute '__name' # # son.__privatefunc() # AttributeError: 'AA' object has no attribute '__privatefunc' # son.func1() ''' @classmethod # 类方法:必须通过类的调用,而且此方法的意义:就是对类里面的变量或者方法进行修改添加。 ''' # class A: # def __init__(self, name, age): # self.name = name # self.age = age # # def func(self): # print('this is a normal function') # # @classmethod # def func2(cls, area, name1): # cls.area = area # cls.name = name1 # # obj = A('name1', 32) # obj.name = 'name2' # obj.age = 22 # print(obj.__dict__) # # obj.func2('area', 'name3') # A.func2('area', 'name3') 可以实现相同的效果 # print(obj.__dict__) # print(A.__dict__) ''' calculate how many times that One class has been sampled ''' # class C: # count = 0 # def __init__(self): # C.cou() # # @classmethod # def cou(cls): # cls.count += 1 # # obj = C() # obj = C() # obj = C() # obj = C() # obj = C() # print(C.count) ''' @staticmethod # 静态方法: 就是一个不依赖类以及对象的一个普通函数,为什么在类里面? # 为了保证代码的一致性,可调控性,整洁性。 ''' # class D: # def __init__(self): # print('initiation') # # @staticmethod # def static_func(name, age): # print(name, age) # # obj = D() # D.static_func('xiaobai', 15) ''' @property ''' # class F(object): # def __init__(self, name, age): # self.name = name # self.age = age # # def func(self): # print('this is a normal function') # # @property # def property_func(self, value): # self.name = value # print('this is a property') # # @property_func.setter # def property_func(self, value): # self.name = value # print(self.name) # print('this is setter') # # @property_func.getter # def property_func(self): # return 'this is getter' # # @property_func.deleter # def property_func(self): # print('this is deleter') # # # obj = F('alex', 12) # obj.property_func = 'test setter' # print(obj.name) # print(obj.property_func) # del obj.property_func ''' 苹果:原始价位8元,折扣价格:0.8 ''' # class Produc: # def __init__(self, name, origin_price, discount): # self.name = name # self.__origin_price = origin_price # self.__discount = discount # # @property # def Price(self): # return self.__origin_price*self.__discount # # @Price.setter # def Price(self, new_price): # self.__origin_price = new_price # # obj = Produc('apple', 20, 0.8) # print(obj.Price) # obj.Price = 30 # print(obj.Price) # print(obj.__dict__) # class Product: # # def __init__(self, name, origin_price, discount): # self.name = name # self.__origin_price = origin_price # self.__discount = discount # @property # def price(self): # return self.__origin_price * self.__discount # # @price.setter # def price(self, new_price): # self.__origin_price = new_price # apple = Product('苹果', 8, 0.95) # # print(apple.price) # apple.price = 7 # print(apple.price) ''' 反射!!!! # 反射:通过 字符串 去操作对象(实例化对象 类, 模块)。 # hasattr() getattr() *** # setattr() delattr() * # 对实例化对象的示例 # isinstance(obj, class): whether obj is an object of class or not # issubclass(class1, class2): whether class1 is a subclass of class2 or not ''' # class A: # pass # # class B(A): # pass # # obj = B() # print(isinstance(obj, B)) # print(issubclass(A, B)) # class A: # name = 'alex' # age = 23 # # def __init__(self, gender, area): # self.gender = gender # self.area = area # # def func(self): # print(self.gender) # # obj = A('male', 'shandong') # # ret = getattr(obj, 'name') # ret = getattr(obj, 'func') # ret() # # ret1 = hasattr(obj, 'func') # print(ret1) # False # ret2 = setattr(obj, 'height', 1.8) # # ret3 = delattr(obj, 'func') #AttributeError: func (object has no function attributes) # # delattr(A, 'func') # print(ret) # print(ret1) # print(obj.__dict__) # print(A.__dict__) # 对类 # class A: # # name = 'alex' # def __init__(self): # pass # # def func(self): # print('IN func') # # # print(getattr(A, 'name')) # # ret = getattr(A, 'func') # # ret(1) # ret = input('>>>>') # 'func' # f1 = getattr(A, ret)(1) # 对当前模块(文件) # def func(): # print('in func') # # # import sys # # current_module = sys.modules[__name__] # # getattr(current_module, 'func')() # # 对其他模块(文件) # import fs # print(getattr(fs, 'name')) # ret = getattr(fs, 'func') # ret() # # # call the function in class in another module # getattr(fs.test, 'func2')(1) # TypeError: func2() missing 1 required positional argument: 'self' # import fs # # print(getattr(fs,'n1')) # ret = getattr(fs,'func') # ret() # # # 方法一: # clas = getattr(fs, 'A') # print(clas.name) # # # 方法二: # print(getattr(fs.A, 'name')) # getattr(fs.A, 'func2')(1) ''' double-underlined function 1, __str__, __len__, 把对象当作字符串进行一系列操作时,对应的反应,必须包含return,且return必须返回对应操作需返回的数据类型; ''' # # class A: # def __init__(self): # self.a=1 # self.b=2 # pass # # def __str__(self): # print('this is __str__ method') # return '__str__ return' # # def __len__(self): # print('this is __len__ method') # return len(self.__dict__) # # def __hash__(self): # return hash(str(self.a)) # # def __repr__(self): # return 'this is __repr__' # # def __call__(self, *args, **kwargs): # return # # def __eq__(self, other): # if self.a == other: # return True # else: # return False # # def __del__(self): # return 'this is deleting an object' # # # obj = A() # print(obj) # print(len(obj)) # TypeError: object of type 'A' has no len() # print(hash(obj)) # print(repr(obj)) # print('%r' % obj) # %r, show initial data type # test_repr = '123' # print('%r' % test_repr) # '123' # print('%s' % test_repr) # 123 # print(obj == 4) # class A: # def __init__(self): # pass # def __str__(self): # print(666) # return '太白' # a = A() # # print(a) # ret = '姓名:%s' % a # print(ret) # class A: # def __init__(self): # pass # def __repr__(self): # return '太白' # a = A() # # print(repr(a)) # print('%r'%a) # class Foo: # # def __init__(self): # pass # # def __call__(self, *args, **kwargs): # print(args) # print('__call__') # # obj = Foo() # obj('WuSir', 'alex') # 对象() 触发 __call__()方法 # __new__ # 讨论的 __init__ __new__ 先后顺序 # class A: # def __init__(self): # self.x = 1 # print('in init') # # def __new__(cls, *args, **kwargs): # print('in __new__') # return object.__new__(cls) # # obj = A() # print(obj.x) # 设计模式:单例模式:让一个类的实例化对象有且只有一个。 *** # class A: # pass # ret = A() # ret1 = A() # print(ret, ret1) # class A: # __instance = None # def __new__(cls, *args, **kwargs): # if cls.__instance is None: # obj = object.__new__(cls) # cls.__instance = obj # return cls.__instance # # ret1 = A() # ret2 = A() # ret3 = A() # print(ret1, ret2, ret3) # __item__系列 __getitem__ __setitem__ __delitem__ *** # 对一个对象进行类似于字典的操作,就会触发__item__系列的某个方法。 # class Foo: # def __init__(self, name): # self.name = name # # # def __getitem__(self, item): # # # print('__getitem__此方法执行了') # # # print(item) # # # return self.item # self.'name' # # return self.__dict__[item] # # def __setitem__(self, key, value): # # self.key = value # # def __delitem__(self, key): # print('del obj[key]时,我执行') # # self.__dict__.pop(key) # # def __delattr__(self, item): # # print('del obj.key时,我执行') # # self.__dict__.pop(item) # # # f = Foo('alex') # # print(f['name']) # # f['age'] = 25 # del f['name'] # print(f.__dict__) ''' serializable modules: pkl, json, shelve json: 网络传输 1. json.dump(obj, fp)方法接收一个文件句柄,直接将字典转换成json字符串写入文件 2. json.load(fp)方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 ''' # import json # json.dumps()/json.loads() are for data transmission between different tools, # eg., python and Java # dic = {'name': 'alex', 'age': 18, 'gender': 'male'} # ret = json.dumps(dic, ensure_ascii=False) # 序列化过程 : 就是变成一个特殊的字符串 # print(ret) # json-typed string are characterized with double quotes # print(dic) # python-typed string are characterized with single quotes # # result = json.loads(ret) # 反序列化:将序列化的特殊字符串反解成原来的类型。 # print(result) # dic.dump()/dic.load(): # f = open('json_file', 'w') # ret = json.dump(dic, f) # json.dump(): requires two arguments, content that required to be written, and file that required to be written in # f.close() # f = open('json_file', 'r') # print(json.load(f)) # # json.load() : only file to be read is necessary # f.close() # exercise 2 # dic2 = { # 1: {'name': 'alex', 'age': 23, 'gender': 'male'}, # 2: {'name': 'alex', 'age': 23, 'gender': 'female'}, # 3: {'name': 'alex', 'age': 23, 'gender': 'male'}, # 4: {'name': 'alex', 'age': 23, 'gender': 'male'} # } # dumps/loads # ret = json.dumps(dic2, ensure_ascii=False) # print(ret) # print(json.loads(ret)) # dump/load # f1 = open('json_file2', 'w') # json.dump(dic2, f1) # f2.close() # f2 = open('json_file2', 'r') # print(json.load(f2)) # f2.close() ''' pkl:只用于Python语言之间的传输,包含所有的python支持的数据类型。 pickle.dump()/pickle.load():写入文件 (这个不仅可以写常规的数据,还可以将对象写入) ''' import pickle # dic = {'name': 'xiaobai', 'age': 22, 'gender': 'male'} # ret = pickle.dumps(dic) # print(ret) # # print(pickle.loads(ret)) # f1 = open('pkl_file', 'wb') # data in bytes-type was written # pickle.dump(dic, f1) # f1.close() # # f2 = open('pkl_file', 'rb') # default mode='r', 'rb' has to be set # print(pickle.load(f2)) # class A: # name = 'xiaobai' # def func(self): # print(111) # # f1 = open('pkl_file2', 'wb') # pickle.dump(A, f1) # f1.close() # # f2 = open('pkl_file2', 'rb') # pickle.load(f2).func(1) ''' random package ''' # import random # stupied method # def select(): # char_lis = [] # num_lis =[] # for i in range(97, 123): # char_lis.append(chr(i)) # for i in range(0, 10): # num_lis.append(i) # i = 0 # code ='' # while i < 5: # i += 1 # a = random.sample(char_lis) # b = random.sample(num_lis) # c = random.sample(a, b) # code += c # return code # print(select()) # smarter one: create random codes including capitalized and lower-cased characters and numbers # def code(): # codes = '' # for i in range(1, 6): # num = str(random.randint(0, 9)) # capitalized_char = chr(random.randint(97, 122)) # lowercased_char = chr(random.randint(65, 90)) # c1 = random.choice([num, capitalized_char, lowercased_char]) # codes += c1 # return codes # # # print(code()) # # print(random.sample([1, 3, 5, 'a'], 2)) # two arguments required: iterable para, number # print(random.random()) # return float between 0-1 # print(random.randrange(1, 3)) # randrange: exclude lower bound # print(random.randint(10, 11)) # randint: include lower bound # print(random.uniform(0, 10)) # float between upper and lower bounds