Discuss / Python / @property 与 __init__

@property 与 __init__

Topic source

Paranoid_Qian

#1 Created at ... [Delete] [Delete and Lock User]

廖老师,我有个疑问:

@property可以定义一些属性,那这种方式会跟init方法中定义冲突么?

还是@property定义的属性是init基础上的补充?

Paranoid_Qian

#2 Created at ... [Delete] [Delete and Lock User]

廖老师,我稍微改了下Screen,发现有个问题:

  1. 用@property定义的属性,在外部仍然可以跳过setter和getter机制,直接调用__width,即使我按照访问限制那一节,添加了前缀下划线
  2. 通过s.__width改变属性,结果s.width并没有被改变,难道这两个操作改变的不是一个属性??

但是如果另外在init中直接定义一个__height,则解释器会报错,执行访问限制。

是不是只有在init中直接定义的属性才能满足python解释器的访问限制,其他的都要靠写代码自觉?

class Screen(object):

    def __init__(self, height):
        self.__height = height

    @property
    def width(self):
        print('through getter: ')
        return self.__width

    @width.setter
    def width(self, width):
        # add some checks...
        print('through setter: %s' % width)
        self.__width = width

    @property
    def resolution(self):
        return self.__width**2

s = Screen(80)
s.width = 60  # 转化为setter操作
print(s.width)  # 转化为getter操作

# 尽管定义时采用了双下划线,但是仍然可以直接访问???
s.__width = 50  # 不经过setter
print(s.__width)  # 不经过getter
print(s.width)  # 经过getter,而且没有受到上两行的影响??

# 这里地__height就不可以访问了. 
# print(s.__height)

廖雪峰

#3 Created at ... [Delete] [Delete and Lock User]

你在外部写s.__width=50和内部的变量__width不是同一个变量,因为外部是无法直接访问实例变量__width

把变量名__width改成value_of_width再测

Paranoid_Qian

#4 Created at ... [Delete] [Delete and Lock User]

也就是我在外部写的s.__width实际上是给s对象动态增加了一个属性,相当于屏蔽了类定义的__width属性,对吧?

而且这个s.__width属性实际上对于其他的对象也不存在。

廖老师,这样理解对么?


  • 1

Reply