019-2018-09-28 反射
阿新 • • 發佈:2018-12-19
1.今日內容大綱
一. 昨日內容回顧 1. 關係 1. 依賴關係. 在方法中傳遞引數. 2. 關聯關係. self.xxx = xxxx 3. 繼承關係. self是什麼? 當前正在執行方法的物件 4. 特殊成員: __init__() __new__() __getitem__() obj[xxx] __setitem__() obj[xxx] = xxxx __delitem__() del obj[xxx] __call__() obj() __str__() print(obj) 返回這個物件的字串表示形式 __enter__() __exit__() with 二. 作業講解 三. 今日主要內容 1. issubclass, type, isinstance issubclass 判斷xxxx類是否是xxxx類的子類 type 給出xxx的資料型別. 給出建立這個物件的類 isinstance 判斷xxx物件是否是xxx型別的 2. 如何分辨方法和函式. 在外面定義的函式一定是函式 在類中: 1. 例項方法: 如果是物件訪問.方法,, 如果是類名訪問是函式 2. 靜態方法: 都是函式 3. 類方法: 都是方法 如果想要用程式來判斷. 需要引入兩個模組 from types import FunctionType, MethodType isinstance() 3. 反射(重點) 僅限於記憶體層面 重點: hasattr(obj, str) 判斷物件中是否包含了xxx(str) getattr(obj, str) 從物件中獲取xxxx(str) 次重點: setattr(obj, str, value) 給物件設定xxxx(str)屬性值(value) delattr(obj, str) 從物件中刪除xxxxx(str)資訊
2.練習
# class UserInfo(object): # pass # # class Department(object): # pass # # class StarkConfig(object): # def __init__(self, num): # self.num = num # # def changelist(self, request): # print(self.num, request) # # def run(self): # self.changelist(999) # # class RoleConfig(StarkConfig): # # def changelist(self, request): # print(666, self.num) # # class AdminSite(object): # def __init__(self): # self._registry = {} # def register(self, k, v): # k:UserInfo, v:StarkConfig # self._registry[k] = v(k) # # # site = AdminSite() # # site.register(UserInfo, StarkConfig) # {UserInfo:StarkConfig(Userinfo)} # # site.register(Department, RoleConfig) # {UserInfo:StarkConfig(Userinfo), Department:RoleConfig(Department)} # # # # for k, row in site._registry.items(): # # row.run() class UserInfo(object): pass class Department(object): pass class StarkConfig(object): def __init__(self, num): self.num = num def get_vals(self): v = [11, 22, 33] extra = self.extra_vals() if extra: v.extend(extra) return v def extra_vals(self): pass def run(self): return self.get_vals() class RoleConfig(StarkConfig): def extra_vals(self): return [99, 88] class AdminSite(object): def __init__(self): self._registry = {} def register(self, k, v): self._registry[k] = v(k) site = AdminSite() site.register(UserInfo, StarkConfig) site.register(Department, RoleConfig) # {UserInfo:StarkConfig(Userinfo), Department:RoleConfig(Department)} for k, row in site._registry.items(): print(row.run()) # StarkConfig(Userinfo).run() # RoleConfig(Department).run()
3.補充練習2
class User: def __init__(self, id, nick_name, login_name, login_psw, real_name, card, phone, address, email): self.id = id self.nick_name = nick_name self.login_name = login_name self.login_psw = login_psw self.real_name = real_name self.card = card self.phone = phone self.address = address self.email = email self.order_list = [] class Order: # 訂單編號, 流⽔號, 所屬⽤戶編號, 收貨地址. 郵費. 訂單狀態(0:發貨, 1:收貨, 2: 退貨), 評價編號. def __init__(self, id, liushui, address, user, pingjia, youfei=0.00, order_status=0): self.order_detail_list = [] pass # 資訊: 評價編號, 評價分數, 評價內容, 評價顯⽰(0:顯⽰, 1:不顯⽰), 評價 # 型別(1: 物流評價, 2: 服務評價, 3: 商品評價) class PingJia: def __init__(self, id, score, content, pingjia_status, isShow=0): pass # 明細編號, ⼩流⽔號, 商品購買時價格, 購買數量. 商品編號 class OrderDetail: def __init__(self, id, xiaoliushui, price, num, product, order): pass # 商品編號, 商品名稱, 商品描述, 商品價格, 商品庫存 class Product: def __init__(self, id, name, desc, price, store): pass
4.補充練習1
from random import randint
class Stu:
def __init__(self, num, name, address):
self.num = num
self.name = name
self.address = address
self.course_list = []
def add_course(self, course):
self.course_list.append(course)
def show(self):
print("學生姓名:%s" % self.name)
for c in self.course_list:
print("選的課程是:%s" % c.name)
if c.teacher:
print("授課老師的電話:%s" % (c.teacher.tel))
else:
print("該課程還沒有老師")
def check(self):
# 1.顯示所有課程.
# 2.選課
# 3.新增到列表中
pass
class Course:
def __init__(self, num, name, teacher=None):
# if teacher != None and isinstance(teacher, Teacher):
self.num = num
self.name = name
self.teacher = teacher
# else:
# raise Exception()
def set_teacher(self, teacher):
self.teacher = teacher
def show(self):
if self.teacher:
print("課程的名稱是:%s, 授課老師是:%s" % (self.name, self.teacher.name))
else:
print("課程的名稱是:%s, 授課老師是:%s" % (self.name, "無"))
class Teacher(object):
def __init__(self, id, name, tel):
self.id = id
self.name = name
self.tel = tel
c1 = Course(1, "體育課")
c2 = Course(2, "生物課")
c3 = Course(3, "歷史課")
c4 = Course(4, "思想品德課")
c5 = Course(5, "電子競技課")
c6 = Course(6, "python課")
t1 = Teacher(1, "周杰倫", 11111)
t2 = Teacher(2, "彭于晏", 11112)
t3 = Teacher(3, "林更新", 11113)
t4 = Teacher(4, "吳彥祖", 11114)
t5 = Teacher(5, "周星馳", 11115)
t6 = Teacher(6, "alex", 11116)
c1.set_teacher(t1)
c2.set_teacher(t2)
c3.set_teacher(t3)
c4.set_teacher(t4)
c5.set_teacher(t5)
c6.set_teacher(t6)
c_lst = [c1, c2, c3, c4, c5, c6]
stu_lst = []
for i in range(30):
stu = Stu(i,"Stu%s" % i,"美麗富饒的沙河")
s = set()
while len(s) < 3:
s.add(randint(0, 5))
for index in s:
stu.add_course(c_lst[index]) # 你選的課
stu_lst.append(stu)
for stu in stu_lst:
stu.show()
5.issubclass
class Animal:
pass
class Cat(Animal):
pass
class BoSiCat(Cat):
pass
print(issubclass(Cat, Animal)) # 判斷第一個引數是否是第二個引數的後代
print(issubclass(Animal, Cat))
print(issubclass(BoSiCat, Animal)) # True
6.type
# class Animal:
# pass
#
# class Cat(Animal):
# pass
#
# class BoSiCat(Cat):
# pass
#
# c = Cat()
# print(type(c)) # 比較精準的給出物件的類
# 計算a+b的結果並返回. 兩個數相加
# def add(a, b):
# if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
# return a + b
# else:
# print("算不了")
#
# print(add("胡漢三", 2.5))
7.isinstance
class Animal:
pass
class Cat(Animal):
pass
class BoSiCat(Cat):
pass
# a = Animal()
# print(isinstance(a, Animal)) # 自己類可以判斷
# print(isinstance(a, Cat)) # 子類不能判斷
c = BoSiCat()
print(isinstance(c, Animal)) # True 子類的物件可以當成父類的型別來看.
# isinstance判斷的是物件是否是xxx家族體系的內容. 往上找
lst = "馬化騰"
print(type(lst.__iter__()))
8.方法和函式
def func():
print("我是func")
print(func) # <function func at 0x00000253260678C8>
class Foo:
# 例項方法: 物件.方法 方法 類名.方法 函式
def chi(self):
print("我是吃")
@staticmethod # 都是函式
def static_method():
pass
@classmethod # 都是方法
def class_method(cls): # 類物件的內容
pass
@property # 神馬都不是. 變數
def age(self):
return 10
# 引入兩個模組
from types import FunctionType, MethodType
def haha(arg):
print(isinstance(arg, FunctionType)) # False
print(isinstance(arg, MethodType)) # True
haha(Foo.age)
# f = Foo()
# print(f.chi) # <bound method Foo.chi of <__main__.Foo object at 0x0000022D69C48390>>
# Foo.chi(f)
# print(Foo.chi) # <function Foo.chi at 0x000001A4BBEE79D8>
#
# print(f.static_method) # <function Foo.static_method at 0x000002BBD2DB7A60>
# print(Foo.static_method) # <function Foo.static_method at 0x00000233E2247A60>
#
# print(f.class_method) # <bound method Foo.class_method of <class '__main__.Foo'>>
# print(Foo.class_method) # <bound method Foo.class_method of <class '__main__.Foo'>>
9.面向物件的反射
class Person:
def __init__(self, name):
self.name = name
self.age = None
def chi(self):
print("人喜歡吃東西%s" % self.name)
p = Person("劉偉")
setattr(p, "name", "大陽哥") # 動態的給物件設定屬性和值
setattr(p, "age", 18) # 很少用. 慎用
print(p.age)
delattr(p, "age")
print(p.age)
# p.chi()
# val = input("請輸入你想讓劉偉執行的動作:")
# if hasattr(p, val):
# getattr(p, "name")
# func = getattr(p, val)
# func()
10.其他
master.py
def chi():
print("大牛一頓吃100碗飯")
def he():
print("大牛一頓喝一桶")
def la():
print("大牛很能拉")
def shui():
print("大牛一次睡一年")
name = "大牛"
test.py
import master
# while 1:
# print("""大牛寫了很多的功能:
# chi
# he
# la
# shui
# """)
# val = input("請輸入你要測試的功能") # he
#
# if hasattr(master, val):
# attr = getattr(master, val) # 從xxx物件或者模組中找xxxxx(字串) 功能, 變數
# if callable(attr): # 判斷這個鬼東西是否可以被呼叫
# attr()
# else:
# print(attr)
# else:
# print("沒有這個功能")
#
# # master.val()
# #
# # master."chi"()
#
#
# # if val == 'chi':
# # master.chi()
# # elif val == "he":
# # master.he()
# # elif val == "la":
# # master.la()
# # elif val == "shui":
# # master.shui()
# # else:
# # print("滾犢子")
#
# 把chi函式換成lambda
# print(master.chi)
# setattr(master, "chi", lambda x: x + 1)
# print(master.chi)
delattr(master, "la") # 刪除xxx
master.la()