Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Argument handling

Peter Corke edited this pageJun 22, 2020 ·2 revisions

Argument handling in MATLAB

MathWorks have evolved the way they handle optional parameters. It used to be additional parameters to the function and handled byvarargin andnargin. It was often difficult to remember the order and meaning of additional parameters.

They later standardised on keyword-value pairs, where the keyword is a string. For example:

plot(x, y, 'Color', 'red', 'LineWidth', 2)

where the keyword is a character array (single quotes) or a string (double quotes).

Code support in MATLAB was originally quite sketchy but from 2007 there isinputParser which is a bit like Python'sargparse for command line arguments.

Since their support was sketchy I wrotetb_optparse to do the job, but it's not strict about keyword-value pairs. In addition it lets you handle keyword-only options like:

R = rotx(30, 'deg')

that can have a negative form like:

R = rotx(30, 'nodeg')

or enum like form

R = rpy2r(angles, 'xyz')R = rpy2r(angles, 'zyx')

Full details are given at the end of this page. The arguments and their defaults are expressed quite concisely using a MATLAB struct.

Python

Python allows both positional or keyword based arguments, and distinguishes between the two. Consider the case ofLink. Using just positional arguments it would be

Link(0, 1, 2, 3)

which makes it difficult for the reader to know what's going on. It also makes it difficult to handle defaults.

Using keyword-value arguments, in MATLAB or Python, would be:

Link('d', 0, 'theta', 1, 'alpha', 2, 'a', 3)

which is easy to read, but a bit cumbersome to write. For MATLABtb_optparse makes it easy to handle the arguments.

function Link(varargin)    opt.d=0    opt.theta=0    opt.alpha=0    opt.a=0    opt= tb_optparse(opt,varargin)

and for Python we could convert the argument into a list of keyword-value tuples by:

def Link(*pos):    kwval = [(pos[i], pos[i+1]) for i in range(0, len(pos), 2)]

and then process the tuples.

The Pythonic way would be to use named arguments

Link(d=0, theta=1, alpha=2, a=3)

We could handle both keyword-value and named arguments with a signature like

def Link(*pos, d=0, theta=0, a=0, alpha=0):

but it would require a lot of logic to work out which types of arguments are being passed, to handle malformed or mixed parameter specifications etc.

We need to make a decision on RTB-M compatibility (a good thing) with ugly code and non-Pythonic expression.

We should decide this relatively early. Do we:

  • cut the cord
  • keep the cord for a few select functions, but then what's the algorithm to choose those?
  • keep compatibility for all functions
  • in the spirit of2to3 do we make the mother of allawk scripts to do this for users

An approach to compatibility

Consider a classMyClass which mimics some class in MATLAB but has Pythonic keyword arguments. We could create a MATLAB compatible version of this from amatlab package which defines the same class but with MATLAB style arguments

matlab/MyClass.py:

import MyClass as mcclass MyClass    def __init__(self, *varargs):        # parse the arguments in varargs to a dict kwargs                self.pythonic = mc.MyClass(**wkargs)    def method1(self, *varargs):        # parse the arguments in varargs to a dict kwargs                return self.pythonic.method1(**wkargs)

We could probably also do something funky with decorators...

Partial documentation fortb_optparse

% The software pattern is:%%         function myFunction(a, b, c, varargin)%            opt.foo = false;%            opt.bar = true;%            opt.blah = [];%            opt.stuff = {};%            opt.choose = {'this', 'that', 'other'};%            opt.select = {'#no', '#yes'};%            opt.old = '@foo';%            opt = tb_optparse(opt, varargin);%% Optional arguments to the function behave as follows:%   'foo'              sets opt.foo := true%   'nobar'            sets opt.foo := false%   'blah', 3          sets opt.blah := 3%   'blah',{x,y}       sets opt.blah := {x,y}%   'that'             sets opt.choose := 'that'%   'yes'              sets opt.select := 2 (the second element)%   'stuff', 5         sets opt.stuff to {5}%   'stuff', {'k',3}   sets opt.stuff to {'k',3}%   'old'              synonym, is the same as the option foo

Clone this wiki locally


[8]ページ先頭

©2009-2025 Movatter.jp