程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Xiaobai Learning Python Series——【Day44】Encapsulation and Polymorphism of the Three Characteristics of Object-Oriented; Object-Oriented Reflection

編輯:Python

今日內容概要

  • A practical exercise of the derivation method(重要)
  • 面向對象三大特性之封裝
  • property偽裝屬性
  • 面向對象三大特性之多態
  • 面向對象之反射(重要)
  • 反射實戰(重要)

A practical exercise of the derivation method(重要)

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

python偽裝屬性

1.The meaning of camouflage
It can be simply understood as disguising methods as data.
Data only needs to be named:obj.name
At 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 decorators

class 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()

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved