我怎样才能以Python的方式将复杂的参数传递给函数?

时间:2018-01-30 18:38:53

标签: python python-3.x function oop

我有一个我必须使用的SOAP Web服务,它支持的一个命令是" SQL like"查询我输入select,from和where语句的位置。我认为"其中"条款将最能证明我在这里尝试这样做:

import tensorflow as tf

dataset1 = tf.data.Dataset.range(5)
dataset2 = tf.data.Dataset.range(5)
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))

iterator = dataset3.make_initializable_iterator()

with tf.Session() as sess:
    sess.run(iterator.initializer)
    next1, next2 = iterator.get_next()
    A = next1

    # Get a second element from `iterator` and add a control dependency to
    # ensure that it is consumed *after* `A` is computed.
    with tf.control_dependencies([A]):
       next3, next4 = iterator.get_next()
    B = next3 + next4

    while True:
        try:
            a, b = sess.run([A,B])
            print(a,b)
        except tf.errors.OutOfRangeError:
            print('done')
            break

基本上,我认为这样做的方法是打包where子句词典列表。但词典应始终具有相同的键。有没有办法在函数定义中定义这种类型?我不想要kwargs或args因为我事先知道数据结构。

我看到的一件事是

def sql_soap(tablename, where):
   sql_where = [soap_object(where_statement) for where_statement in where]
   return query

sql_soap('student',where=[{'Condition':'=','Field':'Subject','Value':'Calculus'}]) 

显然这只适用于较新版本的Python(我有)但我的理解是在期望字典之后的where子句,我想要一个字典列表。

一般来说,当我想要列表中的字典或其他嵌套的东西时,如何定义函数参数?除了字典之外还有什么办法,我可以得到一个函数参数(where)来接受我需要的所有参数来使SOAP成为对象吗?

2 个答案:

答案 0 :(得分:0)

我不知道这是否有帮助,但您可以使用*在哪里预期任意数量的args:

def sql_soap(tablename, *where):
   sql_where = [soap_object(where_statement) for where_statement in where]
   return query

sql_soap('student',
         {'Condition':'=','Field':'Subject','Value':'Calculus'},
         {'Condition':'=','Field':'Subject2','Value':'Calculus2'},
)

你也可以做一件事,但你必须为此修改很多代码,使用namedtuple而不是字典:

from collections import namedtuple

wheretuple = namedtuple("wheretuple", "field condition value")
sql_soap('student', wheretuple("Subject", "=", "Calculus"))

答案 1 :(得分:0)

您尚未指定任何类型。函数定义中的*语法仅指定调用者如何为参数提供参数。可以使用位置参数和关键字参数填充之前的参数,*之后的参数只能使用关键字参数指定。

换句话说,以下调用现在是合法的:

sql_soap('student', where=[...])  # one positional, one keyword argument
sql_soap(tablename='student', where=[...])  # two keyword arguments

但以下不是:

sql_soap('student', [...])  # two positional arguments

您将获得TypeError例外TypeError: sql_soap() takes 1 positional argument but 2 were given

在函数定义中使用*并未说明参数接受的对象类型。您仍然可以将任何您喜欢的内容传递给函数调用。

也许您对函数定义中的*args**kwargs语法感到困惑,其中这些参数捕获了中传递的所有剩余位置或关键字参数,但没有解决任何问题。其他参数。他们对 的参数类型没有任何说法。相反,他们将那些剩余的参数值分别放在元组和字典中。

Python现在支持type hinting,但即使是类型提示也不允许您指定在字典中使用的键。

我在这里使用named tuples,以及类型提示:

from typing import NamedTuple, Sequence

class WhereClause(NamedTuple):
    condition: str
    field: str
    value: str


def sql_soap(tablename: str, where: Sequence[WhereClause]):
    ...

这使得类型检查器知道where参数必须是一个序列类型(如列表),只包含WhereClause个实例。这些实例将具有特定的属性。

只要您想使用任何WhereClause个实例,就可以使用属性来获取内容,因此whereclause.conditionwhereclause.value