1. 程式人生 > >019-2018-09-28 反射

019-2018-09-28 反射

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