Question: I use python mostly as glue-language for numerical simulations. 

Typically I create some wrapper class which initialize some reasonable default parameters, and than elsewhere in larger script I call `run()` method which optionally overrides some parameters and than executes the actual simulation.

It could look something like this: 

```
class MyCalculationClass():

    def __init__():
        # set some defaults
        self.A = 45454
        self.B = np.zeros(16,11)
        self.C = (1.0,2.5,30.0)

    def runRaw():
        return whatever(self.A,self.B,self.C)

    def run( A=None, B=None, C=None ):
        # optionally override some defaults
        if A is not None:
            self.A = A
        if B is not None:
            self.B = B
        if C is not None:
            self.C = C
        # run the actual calculation
        return self.runRaw()

mycalc1 = MyClaculationClass()
# .... Over the Hills and Far Away
mycalc1.run(B=np.zeros(11,12) )

```

but I really **hate the boilerplate** `if A is not None: self.A = A` everywhere. Typically there are tens of parameters.

This would be slightly nicer

```
    def run( A=self.A, B=self.B, C=self.C ):
        # optionally override some defaults
        self.A = A
        self.B = B
        self.C = C
        # run the actual calculation
        self.runRaw()

```

but:

* it does not work
* still it is too much boilerplate

NOTE: I really want `self.A` etc. to keep being stored as class property in order to be able to recover which parameters I used in which calculation later in the larger script

Answer: 
if you don't mind loosing a bit of the automagic documentation provided by inspection, you could do something like this:

```
class Foo(object):
    def __init__(self):
        self._set(A=42, B=[], C="something")

    def _set(self, **kw):
        for name, val in kw.items():
            if val is not None:
                setattr(self, name, val)

   def run(self, **kw):
       self._set(**kw)
       self.runRaw()

```

If you want to keep the `run()` signature intact, it's possible but won't be as generic (since `run()` has to know it's params) :

```
   def run(self, A=None, B=None, C=None):
       self._set(A=A, B=B, C=C)
       self.runRaw()

```

Also note that Python objects can be made callable by declaring a `__call__` method:

```
class NotAFunc(object):
    def __call__(self, arg):
        print("{} called with {}".format(self, arg))

f = NotAFunc()
f(42)

```
This may also be possible with a decorator:

```
import functools

def set_if_none(method):
    @functools.wraps(method)
    def wrapper(self, **kwargs):  # no *args without inspect.signature
        for k, v in kwargs.items():
            if v is not None and hasattr(self, k):
                setattr(self, k, v)
        result = method(self, **kwargs)  # no *args
        return result
    return wrapper

```

Note: the above example only works for (uses and enforces) keyword arguments. To incorporate positional arguments, you'd probably need `inspect.signature`.

Example:

```
class MyClass(object):

    def __init__(self, a=1, b=2):
        self.a = a
        self.b = b

    def __repr__(self):
        return 'MyClass(%s)' % self.__dict__

    @set_if_none
    def meth(self, a=None, b=None):
        pass

>>> mc = MyClass()

>>> mc
MyClass({'a': 1, 'b': 2})

>>> mc.meth(a=10)

>>> mc
MyClass({'a': 10, 'b': 2})

```

Credit to [this answer](https://stackoverflow.com/a/51542306/7954504) for the reminder that you can modify the class instance by passing `self` (the instance) to `wrapper()`, in the decorator.