在python中通用对象的工厂函数是很容易实现的。这得益于python的动态语言特性,以及python中,类亦是对象的设计。
- 下面看一个简单的通用对象的工厂函数:
def factory(aCalss,*args):
return aClass(*args)
就这样简单的两句代码,就实现了一个对象工厂函数。如果使用lambda,甚至可以使用一句代码来完成:factory = (lambda aClass,*args:aClass(*args))
为什么说上述的factory()函数说一个通用对象的工厂函数呢?
- 假设有如下两个类
Person&Cat,怎么通过factory()函数来创建实例?
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
class Cat:
def __init__(self, name, color):
self.name = name
self.color = color
创建对象代码如下:
p = factory(Person,'Kick Chen',59)
c = factory(Cat,'tomCat','black')
print(p, c)
# <Person:name=Kick Chen,age=59> <Cat:name=tomCat,color=black>
- 通过这个示例可以看出这个通用对象的工厂函数说可行的。
- 而且,看一下
factory()函数的实现就明白了。实际上,和普通的对象实例化的操作没有任何的区别,只是在外面包装了一层函数而已。
对于此工厂函数,还有没有可优化的点:当然有。就是加上对关键字参数对支持。
def factory(aClass,*args,**kwargs):
return aClass(*args,**kwargs)
假设有如下类:
class Apple:
def __init__(self, weight,color = 'red',sweet = True):
self.weight = weight
self.color = color
self.sweet = sweet
调用方式如下:
a = factory(Apple,1.5,sweet = False,color = 'green')
p = factory(Person,'rose',24)
print(a,p)
# <Apple:weight=1.5,color=green,sweet=False> <Person:name=rose,age=24>
这样,一个通用的对象工厂函数就实现了。
当然,有以下注意点:
- 该工厂函数,不仅仅可以用来返回对象,也可以传入函数,或者普通对象,用来做其他的事情
关于上面的
*args&**kwargs,作为函数形参,及实参时表达的含义是不同的*args作为形参时,是作为封包来使用的。比如,传入1,2,3,4这4个参数,那么*的作用是封包/压缩。将1,2,3,4转化为(1,2,3,4)这样的一个元祖。实际上函数得到的也是这样一个元组对象,而不是4个对象。*args作为实参时,*的作用时解包/解压。比如,传的是('tom',23),实际上,相当于传了两个参数'tom',23进来。- *
**kwargs和*args作用类似,只是这里的封包与解包,不再是元祖,而是字典。* **kwargs作为形参时,是作为字典封包来使用的。比如:传入age=23,name='tom',那么,实际上得到是{'age':23,'name':'tom'}**kwargs作为实参时,是作为解包来使用的。比如:传入{'age':23,'name':'tom'},相当于传递了两个关键字参数age=23,name='tom'。
p s: 更多关于
*args&**kwargs的介绍,可以参阅python参数魔法 & python 函数参数魔法
参考资料:《Learning Python》

本文介绍如何在Python中利用动态语言特性和类即对象的概念,实现一个简洁高效的通用对象工厂函数。该函数支持任意数量的位置参数和关键字参数,适用于创建各种类型的对象实例。
2669

被折叠的 条评论
为什么被折叠?



