Python 定义抽象读写属性以强制getter和setter实现 文件

Python 定义抽象读写属性以强制getter和setter实现 文件,python,python-3.x,oop,abstract,Python,Python 3.x,Oop,Abstract,Python文档(版本3.8): 上面的示例定义了一个只读属性;您还可以通过适当地将一个或多个基础方法标记为抽象来定义读写抽象属性: 如果只有一些组件是抽象的,则只有这些组件需要更新,才能在子类中创建具体的属性: 我的代码 预期行为:无法实例化,因为存在未定义的抽象方法 实际行为:无错误地实例化 问题: 为什么这不能实例化?如果在派生类中没有实现setter,如何编写它以使其实例化失败。文档似乎表明这应该是abstractmethod的一个涵盖用例。文档还提供了一个示例,其中getter和set

Python文档(版本3.8):

上面的示例定义了一个只读属性;您还可以通过适当地将一个或多个基础方法标记为抽象来定义读写抽象属性:

如果只有一些组件是抽象的,则只有这些组件需要更新,才能在子类中创建具体的属性:

我的代码 预期行为:无法实例化,因为存在未定义的抽象方法

实际行为:无错误地实例化

问题: 为什么这不能实例化?如果在派生类中没有实现setter,如何编写它以使其实例化失败。文档似乎表明这应该是
abstractmethod
的一个涵盖用例。文档还提供了一个示例,其中getter和setter都是抽象方法,这正是我的目标

参考:

从根本上讲,问题在于getter和setter只是同一个类属性的一部分。在
@property
x
中,您有一个
fget
fset
、和
fdel
,它们组成了getter、setter和deleter(不一定全部设置)。这些可能是抽象的,阻止了init,或者根本不存在

类D
中,您创建了一个新的
@属性
,它完全覆盖父
@属性
,因此不再存在任何抽象setter来阻止初始化该类

from abc import ABC, abstractmethod
class C(ABC):
    @property
    def x(self):
        pass

    @x.setter
    @abstractmethod
    def x(self, val):
        pass

class D(C):
    @property
    def x(self):
        pass

def examine_property(p):
    print('get', p.fget, getattr(p.fget, '__isabstractmethod__', False) if p.fget is not None else None)
    print('set', p.fset, getattr(p.fset, '__isabstractmethod__', False) if p.fset is not None else None)
    print('del', p.fdel, getattr(p.fdel, '__isabstractmethod__', False) if p.fdel is not None else None)

print("C.x:")
examine_property(C.x)
print("D.x:")
examine_property(D.x)
输出:

C.x:
get <function C.x at 0x101ac4550> False
set <function C.x at 0x101ac45e0> True
del None None
D.x:
get <function D.x at 0x101ac4670> False
set None None
del None None
C.x:
get <function C.x at 0x1022fb550> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function D.x at 0x1022fb670> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function C.x at 0x10cdd74c0> False
set <function D.x at 0x10cdd7670> False
del None None
# Our new override property is gone
D.x:
get <function D.x at 0x105048670> False
set None None
del None None
# We entirely lost the `setter`
输出:

C.x:
get <function C.x at 0x101ac4550> False
set <function C.x at 0x101ac45e0> True
del None None
D.x:
get <function D.x at 0x101ac4670> False
set None None
del None None
C.x:
get <function C.x at 0x1022fb550> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function D.x at 0x1022fb670> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function C.x at 0x10cdd74c0> False
set <function D.x at 0x10cdd7670> False
del None None
# Our new override property is gone
D.x:
get <function D.x at 0x105048670> False
set None None
del None None
# We entirely lost the `setter`
输出:

C.x:
get <function C.x at 0x101ac4550> False
set <function C.x at 0x101ac45e0> True
del None None
D.x:
get <function D.x at 0x101ac4670> False
set None None
del None None
C.x:
get <function C.x at 0x1022fb550> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function D.x at 0x1022fb670> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function C.x at 0x10cdd74c0> False
set <function D.x at 0x10cdd7670> False
del None None
# Our new override property is gone
D.x:
get <function D.x at 0x105048670> False
set None None
del None None
# We entirely lost the `setter`
输出:

C.x:
get <function C.x at 0x101ac4550> False
set <function C.x at 0x101ac45e0> True
del None None
D.x:
get <function D.x at 0x101ac4670> False
set None None
del None None
C.x:
get <function C.x at 0x1022fb550> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function D.x at 0x1022fb670> False
set <function C.x at 0x1022fb5e0> True
del None None
D.x:
get <function C.x at 0x10cdd74c0> False
set <function D.x at 0x10cdd7670> False
del None None
# Our new override property is gone
D.x:
get <function D.x at 0x105048670> False
set None None
del None None
# We entirely lost the `setter`
D.x:
弄虚作假
设置无无无
无
#我们完全失去了二传手`