# -*- 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