我在Python 3中遇到以下情况:
class A:
d = {}
class B(A): pass
class C(A): pass
我只使用类,没有创建实例。当我访问B.d
时,我会获得对A.d
的共享引用。那不是我想要的。我希望每个继承A
的类都有自己的d
,它被设置为字典。 d
是A
的实施细节。对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_()
的东西在派生时被调用(或在)每个派生类中?
答案 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 ()尽管......