首页 > 解决方案 > 避免类实例覆盖默认值

问题描述

我正在处理有关类初始化的问题。这是一个强调潜在问题的复制示例(我没有设法使它变得更小):

课程

我们有两个班A,B。层次结构去

  1. A: 第一类 - 实例有两个属性link;name
  2. B: 这个类有一个A-instance 作为它的属性之一。

为了更快地声明实例,B我考虑了以下内容:B(name=name)幕后是哪个B(a=A(name=name))

这是代码

 class A(object):
    def __init__(self, link='', name=''):
        self.name = name
        self.link = link

class B(object):
    def __init__(self, a=A(), value=0, link='', name=''):
        # Two ways to initialize "self.a":
        # 1. If "name" or "link" provided
        # 2. With "a" provided
        if {name, link}.difference({''}):
            self.a = A(name=name, link=link)
        else:
            self.a = a
        # Rest
        self.value = value

    def __str__(self):
        return 'Instance:\nname:\t{}\nlink:\t{}\nvalue:\t{}'.format(self.a.name, self.a.link, self.value)

测试

这里有两个小测试:

  1. 第一个b1;b2使用定义了两个实例__init__
  2. 第二个将实例定义为空 ( B()),然后继续填充/覆盖字段。

如下所示,第二个选项是有问题的,因为它覆盖了类的默认值。

# 1. Set it all inside init
b1 = B(link=link, name=name, value=value)
b2 = B(value=value)
print(b1)
# Instance:
# name: world
# link: hello
# value:    1
print(b2) 
# Instance:
# name: 
# link: 
# value:    1

# NO PROBLEM

# 2. Define empty instances and populate
b1 = B()
b1.a.link = link
b1.a.name = name
b1.value = values[0]
b2 = B()
b2.value = values[1]
print(b1)
# Instance:
# name: world
# link: hello
# value:    1
print(b2)
# Instance:
# name: world
# link: hello
# value:    2

# PROBLEM

我如何保证不会出现这个问题?我应该覆盖__new__方法、添加 getter/setter、使用副本 ( copy.deepcopy) 等吗?

标签: pythonoop

解决方案


推荐阅读