# Author: Ghost# Email: jiaci.liu@gmail.com'''1-Review of last week2-interface class, abstract class3-packing4-special methods classmethod staticmethod property5-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 it2. 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 function1, __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, shelvejson: 网络传输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