1.前戲
import datetime import json d = { 't1':datetime.datetime.today(), 't2':datetime.date.today() } res = json.dumps(d) print(res) ''' TypeError: Object of type 'datetime' is not JSON serializable '''
(1)此處代碼會報錯,無法正常序列化,原因是json序列化pythonData types are limited,Not available for all types.
(2)利用json.JSONEncoder查看jsonSerialization can be applied to data types
(3)上述jsonThe stored data is time type,所以不會被序列化.The data to be serialized,Both inside and out must be guaranteed to be of the above type.
2.引出
For the above data types that cannot be serialized,The following solutions are given.
(1)解決方式一:
Manually convert non-conforming data types to conforming ones.import datetime import json d = { 't1':str(datetime.datetime.today()), 't2':str(datetime.date.today()) } res = json.dumps(d) print(res) ''' {"t1": "2022-07-28 15:48:31.269905", "t2": "2022-07-28"} '''
(2)解決方式二:
Use derived methods.查看dumpsmethod after:
class JSONEncoder: pass dumps(obj,cls=None): if cls == None: cls = JSONEncoder return cls(...) # JSONEncoder()
(1)查看JSONEncoderThe source code found that there is a serialization errordefault方法觸發的
raise TypeError(f'Object of type { o.__class__.__name__} ' f'is not JSON serializable')
(2)If we want to avoid errors 那麼肯定需要對default方法做修改(派生)
import datetime import json d = { 't1':datetime.datetime.today(), 't2':datetime.date.today() } class MyJsonEncode(json.JSONEncoder): def default(self, o): '''o就是jsonThe data to be serialized''' if isinstance(o, datetime.datetime): return o.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(o, datetime.date): return o.strftime('%Y-%m-%d') # If it is a serializable type 那麼不做任何處理 Just serialize it directly return super().default(o) res = json.dumps(d, cls=MyJsonEncode) print(res) json.dumps(d, cls=MyJsonEncode)
1.封裝的概念
Encapsulation is actually hiding data or functions;The purpose of hiding is not to make it unavailable to users,Instead, a specific interface is opened for these hidden data,Let users use the interface before they can use it,We add some extra operations to the interface.
2.Encapsulates hidden features
(1)Names starting with a double underscore during class definition are hidden properties.
Subsequent classes and objects cannot be obtained directly
(2)在pythondoesn't really restrict any code in it.
Hidden properties if really need to be accessed,It can also be deformed.But this loses its hidden meaning!!!
3.封裝實例——代碼展示
class Student(object): __school = '清華大學' def __init__(self, name, age): self.__name = name self.__age = age # 專門開設一個訪問學生數據的通道(接口) def check_info(self): print(""" 學生姓名:%s 學生年齡:%s """ % (self.__name, self.__age)) # 專門開設一個修改學生數據的通道(接口) def set_info(self,name,age): if len(name) == 0: print('用戶名不能為空') return if not isinstance(age,int): print('年齡必須是數字') return self.__name = name self.__age = age stu1 = Student('jason', 18) print(stu1._Student__name) ''' jason ''' # Change the name method: stu1.set_info('kevin',20) print(stu1._Student__name) ''' kevin'''
4.Gentleman's Agreement on Code Encapsulation
我們在編寫pythonMost of the time it's something that everyone sticks to,No real restrictions are needed(君子協定):class A: _school = '清華大學' def _choice_course(self): pass
1.The meaning of camouflage
It can be simply understood as disguising methods as data.Data only needs to be named:
obj.nameAt a minimum, the method must be parenthesized:
obj.func()
After disguise you canfuncMethods masquerading as data:obj.func
2. @propertymain function
Specific case code display:(1)# No decorators are [email protected]之前————p1.BMI() #加括號調用
class Person: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height def BMI(self): return self.weight / (self.height ** 2) # No decorators are [email protected]之前 p1 = Person('jason',57,1.73) res = p1.BMI() # 加括號調用 print(res) ''' 19.045073340238563''' """BMIAlthough it needs to be calculated But more like human data"""
(2)# 添加裝飾器@property之後————p1.BMI #直接調用
class Person: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property def BMI(self): return self.weight / (self.height ** 2) # 添加裝飾器@property之後 p1 = Person('jason', 78, 1.83) print(p1.BMI) # 23.291229956104985 print(p1.name) # jason
3.The deepening of the knowledge point is the thoroughness of the camouflage(了解)
需求:Added user modification and deletion decoratorsclass Foo: def __init__(self, val): self.__NAME = val # 將屬性隱藏起來 @property def name(self): return self.__NAME @name.setter def name(self, value): if not isinstance(value, str): # 在設定值之前進行類型檢查 raise TypeError('%s must be str' % value) self.__NAME = value # 通過類型檢查後,將值value存放到真實的位置self.__NAME @name.deleter def name(self): raise PermissionError('Can not delete') obj = Foo('jason') print(obj.name) # jason obj.name = 'kevin' print(obj.name) # kevin del obj.name # PermissionError: Can not delete
1.The literal meaning of polymorphism
多態:一種事物的多種形態
水:液態 氣態 固態
動物:人 狗 貓 豬
2.Specific example code display
(1)案例一:Foreplay animal calls separate method calls:
class Animal(object): def spark(self): pass class Cat(Animal): def miao(self): print('喵喵喵') class Dog(Animal): def wang(self): print('汪汪汪') # c1 = Cat() d1 = Dog() c1.miao() # 喵喵喵 d1.wang() # 汪汪汪 """ 一種事物有多種形態,But the same function should have the same name; In this case, we will get a specific animal in the future,You don't even need to know what kind of animal it is,>Just call the same function directly. """
Different animal calls are elicited in one way(spark)調用:
""" eg: Whether it is chicken, duck, dog or pig,As long as the call is made, the fixed function that belongs to the call is called!!! """ class Animal(object): def spark(self): pass class Cat(Animal): def spark(self): print('喵喵喵') class Dog(Animal): def spark(self): print('汪汪汪') c1.spark() # 喵喵喵 d1.spark() # 汪汪汪
(2)案例二:
Whether it's a tuple,列表還是字典,Statistical length islen方法調用.
l1 = [11, 22, 33, 44] d1 = { 'name': 'jason', 'pwd': 123, 'hobby': 'raed'} t1 = (11, 22, 33, 44) print(len(l1)) print(len(d1)) print(len(t1))
3.多態性的概念
pythonA mandatory action is also provided,要自覺遵守
import abc # 指定metaclass屬性將類設置為抽象類,抽象類本身只是用來約束子類的,不能被實例化 class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 該裝飾器限制子類必須定義有一個名為talk的方法 def talk(self): # 抽象方法中無需實現具體的功能 pass class Person(Animal): # 但凡繼承Animal的子類都必須遵循Animal規定的標准 def talk(self): pass def run(self): pass obj = Person()
4.鴨子類型
大白話解釋:只要你長得像鴨子,走路像鴨子,說話像鴨子,那麼你就是鴨子.class Teacher: def run(self):pass def eat(self):pass class Student: def run(self):pass def eat(self):pass
5.Polymorphism explained in different systems(Duck type deduction)
(1)linux系統:一切皆文件
As long as you can read the data Can write data Then you are the file
內存
硬盤class Txt: # Txt類有兩個與文件類型同名的方法,即read和write def read(self): pass def write(self): pass class Disk: # Disk類也有兩個與文件類型同名的方法:read和write def read(self): pass def write(self): pass class Memory: # Memory類也有兩個與文件類型同名的方法:read和write def read(self): pass def write(self): pass
(2)python:一切皆對象
只要你有數據 有功能 Then you are the object
文件名 文件對象
模塊名 模塊對象
1.Meaning of reflection
Manipulate data or methods of an object through strings
2.Reflect four methods:
hasattr():Determines whether the object contains a property corresponding to a string
getattr():Get the property corresponding to the object string
setattr():Set properties on objects based on strings
delattr():Removes a property from an object based on a string
3. Reflection example code display
class Student: school = '清華大學' def choice_course(self): print('選課') stu = Student() # 需求:Check whether the name provided by the user is in the scope of the object that can be used # 方式1:利用異常處理(過於繁瑣) # try: # if stu.school: # print(f"True{stu.school}") # except Exception: # print("沒有屬性") """ 變量名school 與字符串school Not much difference stu.school stu.'school' The only difference between the two is the quotation marks But the essence is completely different """ # 方式2:獲取用戶輸入的名字 Then determine whether the moniker exists # while True: # target_name = input('Please enter the name you want to check>>>:').strip() # '''The exception above is even more difficult to implement Reflection is required''' # # print(hasattr(stu, target_name)) # # print(getattr(stu, target_name)) # if hasattr(stu, target_name): # # print(getattr(stu, target_name)) # res = getattr(stu, target_name) # if callable(res): # print('The name obtained is a function', res()) # else: # print('The name you get is a data', res) # else: # print('不好意思 The name you want to find 對象沒有') print(stu.__dict__) stu.name = 'jason' stu.age = 18 print(stu.__dict__) setattr(stu, 'gender', 'male') setattr(stu, 'hobby', 'read') print(stu.__dict__) del stu.name print(stu.__dict__) delattr(stu, 'age') print(stu.__dict__)
4.反射用法
Just see in the needs…字符串或者…Objects then definitely need to use reflection!!!
5.反射實戰案例
class FtpServer: def serve_forever(self): while True: inp = input('input your cmd>>: ').strip() cmd, file = inp.split() if hasattr(self, cmd): # 根據用戶輸入的cmd,判斷對象self有無對應的方法屬性 func = getattr(self, cmd) # 根據字符串cmd,獲取對象self對應的方法屬性 func(file) def get(self, file): print('Downloading %s...' % file) def put(self, file): print('Uploading %s...' % file) obj = FtpServer() obj.serve_forever()