2

I want to check all of my argument values so I can convert the value to None if it's an empty string.

I figured out how to get the list of arguments, but I can't figure out how to get the value of the argument.

What I have now is this:

def __init__(self, first, middle, last):
    # convert blank attributes to None
    import inspect
    args = inspect.getargspec(self.__init__)[0]
    for arg in args:
        print 'arg: ' + str(arg)
        if arg == '':
            arg = None

This gets the argument names, but not their values. How can I get a hold of the values?

2 Answers 2

3

With only 3 arguments, don't bother with inspecting, just refer to them directly, or use a catch-all argument *args:

def __init__(self, *args):
    args = [argument or None for argument in args]

You can access function locals through the locals() dictionary, but it is meant to be read-only, you generally should not use that to set mere defaults.

If you do want a generic approach, I'd use a decorator:

from functools import wraps

def reset_to_none(func):
    @wraps(func)
    def wrapper(*args, **kw):
        args = [arg if not isinstance(arg, str) or arg else None for arg in args]
        kw = {k: arg if not isinstance(arg, str) or arg else None for k, arg in kw.items()}
        return func(*args, **kw)
    return wrapper

then apply that to your __init__ method:

class SomeClass(object):
    @reset_to_none
    def __init__(self, first, middle, last):
        # any of `first`, `middle` or `last` being empty strings will be set to `None`
Sign up to request clarification or add additional context in comments.

7 Comments

There are more than three arguments, I just took out the others to make the post neater. I kind of like giving explicit arguments (rather than *args) because then I get notified if I'm passing the wrong number of arguments to the function elsewhere.
Dang, I just wanted to post an answer with decorators myself. +1
@glglgl: that won't work for instances that have a __bool__ or __nonempty__ or __len__ method returning False. The first argument to methods is self, so self.__len__() could be consulted, replacing self with None. Not pretty.
I meant it for the very first piece of code. For the next ones it is not so easy and your solution is the best. Sorry for being unclear.
The first is a list comprehension replacing the original args sequence with one where empty strings are replaced with None but leaving other values untouched. You can call your function using keyword parameters even when the function itself only has positional parameters, and supporting it here makes the decorator useful to more than just your sample function. :-)
|
2

You could write a decorator that converts all empty string arguments to None:

from functools import wraps

def emptyToNoneParameters (f):
    @wraps(f)
    def inner (*args, **kwargs):
        newArgs = [None if a == '' else a for a in args]
        newKwargs = {k: None if v == '' else v for k, v in kwargs.items()}
        return f(*newArgs, **kwargs)
    return inner

class MyType:
    @emptyToNoneParameters
    def __init__ (self, first, middle, last):
        print(first, middle, last)

x = MyType('a', '', '')
# prints: 'a', None, None

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.