鱼C论坛

 找回密码
 立即注册
查看: 1797|回复: 0

[技术交流] 《零基础入门学习Python》第046讲笔记:魔法方法:描述符

[复制链接]
发表于 2017-8-13 12:53:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
描述符
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)

MyDescriptor 就是描述符类
class MyDescriptor:
        def __get__(self, instance, owner):
                print("getting...", self, instance, owner)
                
        def __set__(self, instance, value):
                print("setting...", self, instance, value)
                
        def __delete__(self, instance):
                print("deleting...", self, instance)

class Test:
        x = MyDescriptor()

MyProperty
class MyProperty:
        def __init__(self, fget=None, fset=None, fdel=None):
                self.fget = fget
                self.fset = fset
                self.fdel = fdel
                
        def __get__(self, instance, owner):
                return self.fget(instance)
        
        def __set__(self, instance, value):
                self.fset(instance, value)
                
        def __delete__(self, instance):
                self.fdel(instance)

class C:
        def __init__(self):
                self._x = None
                
        def getX(self):
                return self._x
        
        def setX(self, value):
                self._x = value
                
        def delX(self):
                del self._x
                
        x = MyProperty(getX, setX, delX)

练习:定义一个温度类,定义两个描述符描述摄氏度和华氏度两个属性。要求:两个属性会自动转化。
# 摄氏度 * 1.8 + 32 = 华氏度
class Celsius:
    def __init__(self, value = 26.0):
        self.value = float(value)
    
    def __get__(self, instance, owner):
        print('__get__被调用了!')
        return self.value
    
    def __set__(self, instance, value):
        print('__set__被调用了!')
        self.value = float(value)

class Fahrenheit:
    def __get__(self, instance, owner):
        return instance.cel * 1.8 + 32
    
    def __set__(self, instance, value):
        instance.cel = (float(value) - 32) / 1.8
        # 这里的instance就等于Temperature
class Temperature:
    cel = Celsius()
    fah = Fahrenheit()

效果:
>>> temp = Temperature()

>>> temp.cel
26.0
>>> temp.fah
78.80000000000001

>>> temp.fah = 100
>>> temp.cel
37.77777777777778

动动手
0
class MyDis:
        def __init__(self, initval = None, name = None):
                self.val = initval
                self.name = name

        def __get__(self, instance, owner):
                print("正在获取变量:" self.name)
                return self.val

        def __set__(self, instance, value):
                print("正在修改变量:" self.name)
                self.val = value

        def __delete__(self, instance):
                print("正在删除变量:" self.name)
                print("这个变量无法删除~")

1
import time

class Record:
        def __init__(self, initval = None, name = None):
                self.val = initval
                self.name = name
                self.filename = "record.txt"

        def __get__(self, instance, owner):
                with open(self.filename, 'a', encoding = 'utf-8') as f:
                        f.write("%s 变量于北京时间 %s 被读取,%s = %s\n" % \
                                (self.name, time.ctime(), self.name, str(self.val)))
                return self.val
        
        def __set__(self, instance, value):
                filename = "%s_record.txt" % self.name
                with open(self.filename, encoding = 'utf-8') as f:
                        f.write("%s 变量于北京时间 %s 被修改,%s = %s\n" % \
                                (self.name, time.ctime(), self.name, str(self.val)))
                self.val = value

2
import os
import pickle

class MyDes:
        saved = []

        def __init__(self, name = None):
                self.name = name
                self.filename = self.name + '.pkl'

        def __get__(self, instance, owner):
                if self.name not in MyDes.saved:
                        raise AttributeError("%s 属性还没有赋值" % self.name)

                with open (self.filename, 'rb') as f:
                        value = pickle.load(f)

                return value

        def __set__(self, instance, value):
                with open(self.filename, 'wb') as f:
                        pickle.dump(value, f)
                        MyDes.saved.append(self.name)

        def __delete__(self, instance):
                os.remove(self.filename)
                MyDes.saved.remove(self.name)

实现效果:及时生成x.pkl, y.pkl,并del时自动删除
>>> 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!'

评分

参与人数 1鱼币 +1 收起 理由
小甲鱼 + 1

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 13:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表