在支持私有構造函數(C#,Dart,Scala等)的語言中,工廠方法ds爲這個問題提供了強大的解決方案。
然而,在Python中,類的構造函數總是可以訪問的,所以你的類的用戶可能很容易忘記工廠方法並直接調用構造函數,產生應該是唯一的對象的重複副本。
使用元類可以實現這個問題的一個傻瓜式解決方案。下面的示例假定零構造函數的參數可以用來唯一標識每個實例:
class Unique(type):
def __call__(cls, *args, **kwargs):
if args[0] not in cls._cache:
self = cls.__new__(cls, *args, **kwargs)
cls.__init__(self, *args, **kwargs)
cls._cache[args[0]] = self
return cls._cache[args[0]]
def __init__(cls, name, bases, attributes):
super().__init__(name, bases, attributes)
cls._cache = {}
可以使用如下:
class Country(metaclass=Unique):
def __init__(self, name: str, population: float, nationalDish: str):
self.name = name
self.population = population
self.nationalDish = nationalDish
placeA = Country("Netherlands", 16.8e6, "Stamppot")
placeB = Country("Yemen", 24.41e6, "Saltah")
placeC = Country("Netherlands", 11, "Children's tears")
print(placeA is placeB) # -> False
print(placeA is placeC) # -> True
print(placeC.nationalDish) # -> Stamppot
總之,如果你想這種做法是非常有用的在運行時產生一組獨特的對象(可能使用其中可能重複條目的數據)。
您不需要構造函數。你需要一個工廠方法。正是因爲這個原因,爲什麼許多爭論的建設者應該是私人的,你應該(幾乎)總是通過工廠方法。 – cletus 2010-09-01 06:40:53