防止在Python

时间:2018-06-01 08:26:32

标签: python python-3.x class inheritance class-variables

我在Python 3中遇到以下情况:

class A:
    d = {}

class B(A):  pass
class C(A):  pass

我只使用类,没有创建实例。当我访问B.d时,我会获得对A.d的共享引用。那不是我想要的。我希望每个继承A的类都有自己的d,它被设置为字典。 dA的实施细节。对d的所有访问均在A的代码中完成。 B d A d__init__()的{​​{1}}不一致。

对于实例,我会在B函数中创建该字典。但就我而言,我只与班级合作。

是否有标准的方法来实现这一点(编辑:不改变子类C__init__()的实现)?是否有类似于from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import sys import multiprocessing from multiprocessing.pool import ThreadPool from multiprocessing.dummy import Pool as DummyPool from multiprocessing import Pool as ProcessPool import time class MainWindow(QMainWindow): finished = pyqtSignal() def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle("QDicomLabel Test") self.resize(500, 500) widget = QWidget() self.setCentralWidget(widget) layout = QHBoxLayout() widget.setLayout(layout) btn = QPushButton('run') layout.addWidget(btn) label = QLabel('0') layout.addWidget(label) self.label = label btn.clicked.connect(self.run) self.num = 0 self.finished.connect(self.updateText) def run(self): num = 4 p = ThreadPool(num) start_time = time.time() ret = p.map(self.readfile, range(200)) p.close() p.join() print("thread_pool %d, costTime: %fs ret.size: %d" % (num, (time.time() - start_time), len(ret))) def readfile(self, name): time.sleep(0.01) # self.signal.finished.emit() def updateText(self): self.num = self.num + 1 self.label.setText(str(self.num)) # QCoreApplication.processEvents() app = QApplication(sys.argv) window = MainWindow() window.show() app.exec_() 的东西在派生时被调用(或在)每个派生类中?

2 个答案:

答案 0 :(得分:1)

我自己使用元类找到了解决方案:

class M(type):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.d = {}

class A(metaclass=M): pass

然后可以创建A的子类,它们都有自己的d属性:

class B(A): pass

B.d is A.d
False

答案 1 :(得分:0)

只需测试@meissner_ comment:您可以轻松地将其子句中的d替换为其他内容。

class BaseA():
    """Provides basic initialization for dicts used in A() and deriveds."""
    @classmethod
    def InitDefaults(cls):
        return { 1: "this", 2:"are", 3:"some", 4:"defaults"}

class A():
    d = BaseA.InitDefaults()

class B(A):
    d = BaseA.InitDefaults()

class C(A):
    d = BaseA.InitDefaults()


print(A.d)
print(B.d)
print(C.d)

print("\n")
B.d[99] = "Not a default"
C.d[42] = "Not THE answer"

print(A.d)
print(B.d)
print(C.d)

输出:

{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}


{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults', 99: 'Not a default'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults', 42: 'Not THE answer'}

这有点难看,但会起作用。你有一个代码修改“base-default”的中心位置,A,B,C得到不同的dicts - 启动相同 - 可以发展到不同的方向。

可能更好的方法是使用Instances和 init ()尽管......