鱼C论坛

 找回密码
 立即注册
查看: 1706|回复: 6

关于描述符的奇怪报错

[复制链接]
发表于 2017-1-21 11:54:53 | 显示全部楼层 |阅读模式

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

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

x
class MyProperty:
    def __init__(self,fget=None,fdel=None,fset=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)
运行后提示:>>> c = C()
>>> c.x = 's'
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    c.x = 's'
  File "E:/Python Practice/MyProperty.py", line 9, in __set__
    self.fset(instance,value)
TypeError: delX() takes 1 positional argument but 2 were given
这个地方学的不是很好,想在悬赏里求助可是用户组等级不够。。。
这个报错报的我心碎了,首先实例出c没问题,可是 执行c.x = 's'报的却是delX()的错,而且还说应该需要一个,但是给了两个,而且还和第九行有关,看了半天看不出来。另外,我买了小甲鱼老师的配套Python书,发现和视频中MyProperty类下的删除方法有所不同,视频中的名称是__del__,而书中的是__delete__,但是无论是哪种,仿佛并没有影响程序的运行,而且我把两种名称改过了之后还是报删除的错,真心是跪了,求版主或小甲鱼老师不吝赐教啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-1-21 17:11:36 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-21 18:00:06 | 显示全部楼层
别着急,就一点点问题,
class MyProperty:
    def __init__(self,fget=None,fset=None,fdel=None):

你把带入的对象的位置设置错误了。还有就是这课后面甲鱼华氏度转摄氏度的例子不好,由于修饰符协议只构造一次实例对象,当你实例很多个对象出来的时候,程序就会出现潜在错误。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-22 17:13:24 | 显示全部楼层
本帖最后由 笑梦灵 于 2017-1-22 17:32 编辑
jackie-L 发表于 2017-1-21 18:00
别着急,就一点点问题,
class MyProperty:
    def __init__(self,fget=None,fset=None,fdel=None):


对的,才知道参数还要考虑位置,谢谢咯,不过温度的那个潜在错误我还没碰到,你说的只构造一次实例对象是指的在temperature类里不应该同时实例华氏和摄氏两个类,还是说不要在shell下实例多个temperature类呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-22 22:06:38 | 显示全部楼层
本帖最后由 jackie-L 于 2017-1-22 22:12 编辑

http://bbs.fishc.com/thread-81771-1-1.html
我在这个帖子中发过的,你可以看看
修饰符类的作用就是封装类属性用的。
我查了相关的资料,小甲鱼在这个例子中把作者的设计这个修饰符类的真正用法弄错了。
你可以把修饰符类理解为一个只做体力劳动的工人,他本身并不为其他雇佣他的人保存任何信息。
而小甲鱼的这个例子中让Celsius这个修饰符类对象为雇佣他的人(也就是Temperature类的实例对象)保存了资料就是self.value = float(value)
当有几个人(Temperature类的多个实例对象)都把信息保存在self.value中的时候这个Celsius工人就会搞不清楚self.value中的值是哪一个雇主的了(因为至始至终值只有一个Celsius的实例对象在工作)。

真实情况是,不管有多少个实例对象调用Celsius这个修饰符类时,都只会只有一个Celsius的实例在为其他调用对象工作。

因为内存中有栈,堆,和方法区,Temperature创建的实例对象都在堆中,只是把对象的地址传给了栈中的主方法区,而堆中的构造的对象中的属性cel都指向一个地方==>方法区==>中的静态区==>中的Celsius对象(只为一个类构造一个对象,为这个类公用)

你应该明白我的意思了吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-2-2 11:20:28 | 显示全部楼层
jackie-L 发表于 2017-1-22 22:06
http://bbs.fishc.com/thread-81771-1-1.html
我在这个帖子中发过的,你可以看看
修饰符类的作用就是封装 ...

先要感谢Jackie的热情回答,回家过年才看到回帖,抱歉了。
你给我发的链接帖我拜读过了,确实存在这样的问题,但是我对产生这种问题的原因还存有一些疑问。
以前学c的时候对内存中的堆栈也了解一些,但你这里说的方法区是相对于堆和栈独立的一片内存区吗,你的意思是Temperature创建的实例对象在堆中,这个实例对象的地址在栈中,实例对象的属性在方法区中,由于存储的空间各不相同,所以实例化新的实例而不改变实例的属性吗,是这个意思吗?不过有一点我有些不太清楚,就是类的属性是否只能在__init__()方法里声明(由于该方法相当于构造函数,一般把初始化数据放在构造函数里,但是Python对语法标准并不苛刻,如果不把属性放在方法里是否也可以),是不是__init__()下的属性在shell下实例的对象都共用一个值呢,那么用描述符来封装的实例岂不是只有一个吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-6 13:18:45 | 显示全部楼层
笑梦灵 发表于 2017-2-2 11:20
先要感谢Jackie的热情回答,回家过年才看到回帖,抱歉了。
你给我发的链接帖我拜读过了,确实存在这样的 ...

恩,你说的差不多啊,描述符类就跟java中的类的静态方法一个道理,是不需要实例化的,直接调用就行了,也就是你说的放在内存中的静态方法区中的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 23:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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