Python's equivalent to null-conditional operator introduced in C# 6

后端 未结 4 2001
时光说笑
时光说笑 2021-01-01 16:04

Is there an equivalent in Python to C# null-conditional operator?

System.Text.StringBuilder sb = null;
string s = sb?.ToString(); // No error
相关标签:
4条回答
  • 2021-01-01 16:45

    Well, the simplest solution would be:

    result = None if obj is None else obj.method()
    

    But if you want the exact equivalent having the same thread safety as the C#'s Null-conditional operator, it would be:

    obj = 'hello'
    temp = obj
    result = None if temp is None else temp.split()
    

    The trade off is that the code isn't really pretty; Also an extra name temp gets added to the namespace.

    Another way is:

    def getattr_safe(obj, attr):
        return None if obj is None else getattr(obj,attr)
    
    obj = 'hello'
    result = getattr_safe(obj,'split')()
    

    Here, trade-off is the function calling overhead, but much clearer code, especially if you are using it multiple times.

    0 讨论(0)
  • 2021-01-01 16:58

    How about:

    s = sb and sb.ToString()
    

    The short circuited Boolean stops if sb is Falsy, else returns the next expression.

    Btw, if getting None is important...

    sb = ""
    
    #we wont proceed to sb.toString, but the OR will return None here...
    s = (sb or None) and sb.toString()
    
    print s, type(s)
    

    output:

    None <type 'NoneType'>
    
    0 讨论(0)
  • 2021-01-01 16:59

    I wrote this function with your required behavior. An advantage of this over chaining and is that it's easier to write when it comes to long chains. Heads up this doesn't work with object keys, only attributes.

    def null_conditional(start, *chain):
        current = start
        for c in chain:
            current = getattr(current, c, None)
            if current is None:
                break
        return current
    

    Here's some tests I ran so you can see how it works

    class A(object):
        b = None
        def __init__(self, v):
            self.b = v
    
    class B(object):
        c = None
        def __init__(self, v):
            self.c = v    
    
    a_1 = A(B(2))
    a_2 = A(None)
    print(null_conditional(a_1, 'b', 'c')) # 2
    print(null_conditional(a_1, 'b', 'd')) # None
    print(null_conditional(a_2, 'b', 'c')) # None
    print(null_conditional(None, 'b')) # None
    print(null_conditional(None, None)) # TypeError: attribute name must be string
    
    0 讨论(0)
  • 2021-01-01 17:03

    There's a proposal under PEP-505, in the meantime there's a library for this:

    from pymaybe import maybe
    
    print(maybe(None).toString())
    
    0 讨论(0)
提交回复
热议问题