[Python]小甲鱼Python视频第046课(魔法方法:描述符(Property的原理) )课后题及参考解答

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 19 22:48:17 2019

@author: fengs
"""


"""
测试题:
0. 请尽量用自己的语言来解释什么是描述符(不要搜索来的答案,用自己的话解释)?
    绑定属性的 set & get & del 方法
"""


"""
1. 描述符类中,分别通过哪些魔法方法来实现对属性的 get、set 和 delete 操作的?
    __get__
    __set__
    __delete__
"""

"""
2. 请问以下代码,分别调用 test.a 和 test.x,哪个会打印“getting…”?

class MyDes:
    def __get__(self, instance, owner):
        print("getting...")
class Test:
    a = MyDes()
    x = a
test = Test()
test.a
test.x

#都会打印 getting 
"""
"""
class MyDes:
    def __get__(self, instance, owner):
        print("getting...")
        return 1
class Test:
    a = MyDes()
    x = a
test = Test()
print(test.a)
print(test.x)
"""

"""
3. 请问以下代码会打印什么内容?
class MyDes:
    def __init__(self, value = None):
        self.val = value

    def __get__(self, instance, owner):
        return self.val - 20

    def __set__(self, instance, value):
        self.val = value + 10
        print(self.val)

class C:
    x = MyDes()

if __name__ == '__main__':  # 该模块被执行的话,执行下边语句。
    c = C()
    c.x = 10
    print(c.x)
    
    20   __set__中打印
    0    __get__中打印

"""

"""
4. 请问以下代码会打印什么内容?
class MyDes:
    def __init__(self, value = None):
        self.val = value
    def __get__(self, instance, owner):
        return self.val ** 2
class Test:
    
    x = MyDes(3)
    
    def __init__(self):
        #self.x = MyDes(3)
test = Test()
test.x


x 并非类属性,test.x的结果将是一个描述符对象

"""

class MyDes:
    def __init__(self, value = None):
        self.val = value
    def __get__(self, instance, owner):
        return self.val ** 2
class Test:
    
    x = MyDes(3)
    
    def __init__(self):
        pass
        #self.x = MyDes(3)
#test = Test()
#print(test.x)



"""
动动手(一定要自己动手试试哦~):
0. 按要求编写描述符 MyDes:当类的属性被访问、修改或设置的时候,分别做出提醒。
程序实现如下:
>>> class Test:
        x = MyDes(10, 'x')

>>> test = Test()
>>> y = test.x
正在获取变量: x
>>> y
10
>>> test.x = 8
正在修改变量: x
>>> del test.x
正在删除变量: x
噢~这个变量没法删除~
>>> test.x
正在获取变量: x
8
""" 

class MyDes0():
    
    def __init__(self,value = None,name = None):
        self.value = value
        self.name = name
    def __get__(self,instance,owner):
        print('正在获取变量: %s ' % self.name )
        return self.value
    def __set__(self,instance,value):
        print('正在修改变量: %s' % self.name )
        self.value = value
    def __delete__(self,instance):
        print('正在删除变量: %s' % self.name )
        print('噢=.=,这个变量没法删除')
        return None

class Test0():
    x = MyDes0(10,'x')
#test0 = Test0()
#print(test0.x)
#test0.x = 8
#del test0.x
#print(test0.x)

"""
1. 按要求编写描述符 MyDes:记录指定变量的读取和写入操作,并将记录以及触发时间保存到文件(record.txt)
程序实现如下:
>>> class Test:
        x = Record(10, 'x')
        y = Record(8.8, 'y')

>>> test = Test()
>>> test.x
10
>>> test.y
8.8
>>> test.x = 123
>>> test.x = 1.23
>>> test.y = "I love FishC.com!"
>>>


"""
import time
class Record():
    
    def __init__(self,value,name):
        self.value = value
        self.name = name
        self.fileSaveName = "record.txt"
        
    def append_line_to_txt(self,txt_line):
        with open(self.fileSaveName,'a') as fid:
            fid.write(txt_line)            

    def __get__(self,instance,owner):
        now = time.asctime()
        txt_line = "%s 变量于北京时间 %s 被读取, %s = %s \n" % (self.name,now,self.name,self.value)
        self.append_line_to_txt(txt_line)
        return self.value
    
    def __set__(self,instance,value):
        now =  time.asctime()
        self.value = value
        txt_line = "%s 变量于北京时间 %s 被修改, %s = %s \n" % (self.name,now,self.name,self.value)
        self.append_line_to_txt(txt_line)
        
class Test1():
    x = Record(10,'x')
    y = Record(8.8,'y')

test1 = Test1()
print(test1.x)
print(test1.y)
test1.x = 123
test1.x = 1.23
test1.y = "I love FishC.com!"


"""
2. 再来一个有趣的案例:编写描述符 MyDes,使用文件来存储属性,属性的值会直接存储到对应的pickle(腌菜,还记得吗?)的文件中。如果属性被删除了,文件也会同时被删除,属性的名字也会被注销。
举个栗子:
>>> class Test:
        x = MyDes('x')
        y = MyDes('y')
        
>>> test = Test()
>>> test.x = 123
>>> test.y = "I love FishC.com!"
>>> test.x
123
>>> test.y
'I love FishC.com!'
产生对应的文件存储变量的值:
"""

import os 
import pickle

class MyDes2():
    def __init__(self,name):
        self.name = name
        self.value = None
        self.file_name = self.name + '.pkl'
    def __get__(self,instance,owner):
        with open(self.file_name,'rb') as fid:
            self.value = pickle.load(fid)
        return self.value
    def __set__(self,instance,value):
        self.value = value
        with open(self.file_name,'wb') as fid:
            pickle.dump(self.value,fid)
        
    def __delete__(self,instance):
        os.remove(self.file_name)
        

class Test2():
    x = MyDes2('x')
    y = MyDes2('y')
    
    
test2 = Test2()
test2.x = 123
test2.y = 'I love Fishc.Com!'
print(test2.x)
print(test2.y)
#del test2.x

  

posted @ 2019-03-24 20:06  Alimy  阅读(443)  评论(0编辑  收藏  举报