Читать книгу SAS Viya - Kevin D. Smith - Страница 20
Constructing Nested Action Parameters
ОглавлениеWhile specifying dictionary parameters, you can suffer from cognitive dissonance when you switch from keyword arguments to dictionary literals. In keyword arguments, you don’t quote the name of the argument, but in dictionary literals, you do quote the key value. Also, in keyword arguments, you use an equal sign between the name and value, whereas in dictionary literals, you use a colon. Because of this potential confusion, we prefer to use the dict constructor with keyword arguments when nesting action parameters. The preceding code is shown as follows, but instead uses the dict object in Python for nested dictionaries.
In [15]: out = conn.echo(
...: list = ['item1',
...: 'item2',
...: dict(
...: key1 = 'value1',
...: key2 = dict(
...: value2 = [0, 1, 1, 2, 3]
...: )
...: )
...: ])
NOTE: builtin.echo called with 1 parameters.
NOTE: parameter 1: list = {'item1', 'item2',
{key1 = 'value1',
key2 = {value2 = {0, 1, 1, 2, 3}}}}
The SWAT package also includes a utility function called vl (for “value list”). This function returns an enhanced type of dictionary that enables you to build nested structures quickly and easily. It can be used directly in place of the dict call in the preceding code in its simplest form, but it can also be used outside of the action to build up parameter lists before the action call.
The primary feature of the dictionary object that vl returns is that it automatically adds any key to the dictionary when the key is accessed. For example, the following code builds the same nested structure that the previous example does.
In [16]: params = swat.vl()
In [17]: params.list[0] = 'item1'
In [18]: params.list[1] = 'item2'
In [19]: params.list[2].key1 = 'value1'
In [20]: params.list[2].key2.value2 = [0, 1, 1, 2, 3]
In [21]: params
Out[21]:
{'list': {0: 'item1',
1: 'item2',
2: {'key1': 'value1', 'key2': {'value2': [0, 1, 1, 2, 3]}}}}
As you can see in Out[21], just by accessing the key names and index values as if they existed, the nested parameter structure is automatically created behind the scenes. However, note that this does make it fairly easy to introduce errors into the structure with typographical errors. The object will create key values with mistakes in them since it has no way of telling a good key name from a bad one.
Using the special dictionary returned by vl does create some structures that might be surprising. If you look at Out[21], you see that the list parameter, which was a Python list in the previous example, is now a dictionary with integer keys. This discrepancy makes no difference to SWAT. It automatically converts dictionaries with integer keys into Python lists.
Using Python’s ** operator for passing a dictionary as keyword arguments, you see, as follows, that we get the same output from the echo action as we did previously while using the contents of our vl object.
In [22]: out = conn.echo(**params)
NOTE: builtin.echo called with 1 parameters.
NOTE: parameter 1: list = {'item1', 'item2',
{key2 = {value2 = {0, 1, 1, 2, 3}},
key1 = 'value1'}}
In addition to constructing parameters, you can also tear them down using Python syntax. For example, the following code deletes the value2 key of the list[2].key2 parameter.
In [23]: del params.list[2].key2.value2
In [24]: params
Out[24]: {'list': {0: 'item1', 1: 'item2',
2: {'key1': 'value1', 'key2': {}}}}
With the ability to construct CAS action parameters under our belt, there are a couple of features of the CAS parameter processor that can make your life a bit easier. We look at those in the next section.