我有几节课。创建实例时,期望的行为是为实例分配了ID。为简单起见,让我们假设ID应该从0开始,并在每次创建实例时增加1。对于这几个类别中的每一个,ID应该独立增加。我知道如何用C++做到这一点。我实际上也已经在Python中做到了,但是我不喜欢C++解决方案,并且我想知道这是否是由于我对Python的了解有限(不到6周),还是有更好的解决方案? ,更Python化的方式。在C++中,我既使用继承又使用合成来实现此目的。两种实现都使用“好奇重复模板模式”(CRPT)惯用语。我稍微喜欢继承方式:#include <iostream>template<class T>class Countable{ static int counter;public: int id; Countable() : id(counter++){}};template<class T>int Countable<T>::counter = 0;class Counted : public Countable<Counted>{};class AnotherCounted: public Countable<AnotherCounted>{};int main(){ Counted element0; Counted element1; Counted element2; AnotherCounted another_element0; std::cout << "This should be 2, and actually is: " << element2.id << std::endl; std::cout << "This should be 0, and actually is: " << another_element0.id << std::endl;}编写方式:#include <iostream>template<class T>class Countable{ static int counter;public: int id; Countable() : id(counter++){}};template<class T>int Countable<T>::counter = 0;class Counted{public: Countable<Counted> counterObject;};class AnotherCounted{public: Countable<AnotherCounted> counterObject;};int main(){ Counted element0; Counted element1; Counted element2; AnotherCounted another_element0; std::cout << "This should be 2, and actually is: " << element2.counterObject.id << std::endl; std::cout << "This should be 0, and actually is: " << another_element0.counterObject.id << std::endl;}现在,在python中,没有模板可以为每个类提供不同的计数器。因此,我将可数类包装到一个函数中,并获得了以下实现:(继承方式)def Countable(): class _Countable: counter = 0 def __init__(self): self.id = _Countable.counter _Countable.counter += 1 return _Countableclass Counted ( Countable() ) : passclass AnotherCounted( Countable() ): passelement0 = Counted()element1 = Counted()element2 = Counted()another_element0 = AnotherCounted()print "This should be 2, and actually is:", element2.idprint "This should be 0, and actually is:", another_element0.id以及组成方式:def Countable(): class _Countable: counter = 0 def __init__(self): self.id = _Countable.counter _Countable.counter += 1 return _Countableclass Counted ( Countable() ) : counterClass = Countable() def __init__(self): self.counterObject = Counted.counterClass()class AnotherCounted( Countable() ): counterClass = Countable() def __init__(self): self.counterObject = self.counterClass()element0 = Counted()element1 = Counted()element2 = Counted()another_element0 = AnotherCounted()print "This should be 2, and actually is:", element2.counterObject.idprint "This should be 0, and actually is:", another_element0.counterObject.id麻烦我的是这个。在C++中,我对自己在做什么很了解,例如即使我的类实际上继承了乘法(不仅仅来自Countable 模板化类),我也没有看到任何问题-一切都非常简单。现在,在Python中,我看到了以下问题:1)当我使用组合时,我实例化了计数类:counterClass = Countable()我必须为每个类都这样做,这可能容易出错。2)当我使用继承时,当我想要繁衍时会遇到更多麻烦。请注意,上面我没有定义Counted或AnotherCounted的__init__,但是如果我继承了乘法,则必须显式调用基类构造函数,或者使用super()。我不喜欢这样(还可以吗?)我也可以使用元类,但是我的知识在那里受到限制,而且似乎增加了复杂性而不是简单性。总而言之,尽管必须使用Countable()显式定义counterClass类属性,但我认为这种组合方式可能更适合Python实现。感谢您对我的结论的有效性的意见。我也希望有比我更好的解决方案的提示。谢谢。 (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 我将使用 __new__ ,这样您就不必记住在__init__中做任何事情了:class Countable(object): counter = 0 def __new__(cls, *a, **kw): instance = super(Countable, cls).__new__(cls, *a, **kw) instance.id = cls.counter + 1 cls.counter = instance.id return instanceclass A(Countable): passclass B(Countable): passprint A().id, A().id # 1 2print B().id # 1 (adsbygoogle = window.adsbygoogle || []).push({});
08-24 21:37