预计阅读本页时间:-
Classes Are Objects: Generic Object Factories
Sometimes, class-based designs require objects to be created in response to conditions that can’t be predicted when a program is written. The factory design pattern allows such a deferred approach. Due in large part to Python’s flexibility, factories can take multiple forms, some of which don’t seem special at all.
Because classes are objects, it’s easy to pass them around a program, store them in data structures, and so on. You can also pass classes to functions that generate arbitrary kinds of objects; such functions are sometimes called factories in OOP design circles. Factories are a major undertaking in a strongly typed language such as C++ but are almost trivial to implement in Python. The call syntax we met in Chapter 18 can call any class with any number of constructor arguments in one step to generate any sort of instance:[71]
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
def factory(aClass, *args): # Varargs tuple
return aClass(*args) # Call aClass (or apply in 2.6 only)
class Spam:
def doit(self, message):
print(message)
class Person:
def __init__(self, name, job):
self.name = name
self.job = job
object1 = factory(Spam) # Make a Spam object
object2 = factory(Person, "Guido", "guru") # Make a Person object
In this code, we define an object generator function called factory. It expects to be passed a class object (any class will do) along with one or more arguments for the class’s constructor. The function uses special “varargs” call syntax to call the function and return an instance.
The rest of the example simply defines two classes and generates instances of both by passing them to the factory function. And that’s the only factory function you’ll ever need to write in Python; it works for any class and any constructor arguments.
One possible improvement worth noting is that to support keyword arguments in constructor calls, the factory can collect them with a **args argument and pass them along in the class call, too:
def factory(aClass, *args, **kwargs): # +kwargs dict
return aClass(*args, **kwargs) # Call aClass
By now, you should know that everything is an “object” in Python, including things like classes, which are just compiler input in languages like C++. However, as mentioned at the start of this part of the book, only objects derived from classes are OOP objects in Python.