Python:高效传递多个变量给函数的方法
我有一堆变量,这些变量的值是从数据库里取出来的。有时候,数据库里没有值,就会返回一个叫“NoneType”的东西。我把这些变量用来生成一个XML文件。但是当变量是NoneType的时候,XML里的值就会显示“None”,而我其实希望它是空白的。
我的问题是:有没有什么简单的方法可以一次性检查所有变量,找出NoneType的情况,如果找到了,就把它变成一个空字符串呢?
比如说:
from types import *
[Connection to database omitted]
color = database.color
size = database.size
shape = database.shape
name = database.name
... etc
我当然可以这样做:
if type(color) is NoneType:
color = ""
但这样对于我有的15个以上的变量来说就太麻烦了。有没有更有效的方法可以检查每个变量的类型,然后在必要的时候进行修正?比如说创建一个函数来做这个检查和修正,然后用自动化的方式把每个变量都传进去这个函数?
4 个回答
我会这样做,虽然我不确定这是不是最好的方法:先把你想检查的变量放到一个列表里,然后用一个循环语句来遍历这个列表。
check_vars = [color,size,shape,name]
for var in check_vars:
if type(var) is NoneType:
var = ""
要添加变量,你只需要把它们放到这个列表里就可以了。
你可以简单地使用:
color = database.color or ""
另一种方法是使用一个函数:
def filter_None(var):
"" if (a is None) else a
color = filter_None(database.color)
我不太清楚数据库对象是怎么结构的,但还有一种解决方案是像这样修改 database
对象:
def myget(self, varname):
value = self.__dict__[varname]
return "" if (value is None) else value
DataBase.myget = myget
database = DataBase(...)
[...]
color = database.myget("color")
你可以通过使用描述符或属性来做得更好。
这里提供的所有解决方案都能让你的代码变得更简洁,不那么繁琐,但如果你有很多变量的话,我想你会特别喜欢这个,因为它不会让你为每个变量增加哪怕一个额外的字符。
class NoneWrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
value = getattr(self.wrapped, name)
if value is None:
return ''
else:
return value
mydb = NoneWrapper(database)
color = mydb.color
size = mydb.size
shape = mydb.shape
name = mydb.name
# All of these will be set to an empty string if their
# original value in the database is none
编辑
我以为这很明显,但我总是忘记,直到所有有趣的Python魔法变成我的第二天性,这需要时间。:) 那么,NoneWrapper
是怎么做到这些魔法的呢?其实很简单。每个Python类都可以定义一些“特殊”的方法名,这些方法名的特点是两边都有两个下划线。最常见、最知名的就是__init__()
,它用来初始化类的每一个实例,但还有很多其他有用的特殊方法,其中之一就是__getattr__()
。这个方法会在有人尝试访问你类的实例的属性时被调用,你可以自定义它来控制属性的访问。
NoneWrapper的作用就是重写getattr,所以每当有人尝试读取mydb(这是一个NoneWrapper实例)的属性时,它会从被包装的对象(在这个例子中是database
)中读取指定名称的属性并返回,除非这个属性的值是None,在这种情况下,它会返回一个空字符串。
我还应该补充一点,对象的变量和方法都是属性,实际上在Python中它们本质上是一样的:所有属性都是可以改变的变量,而方法恰好是值设置为特殊类型函数(绑定方法)的变量。所以你也可以使用getattr()来控制对函数的访问,这可能会带来许多有趣的用法。