[python] C # null 병합 연산자와 동등한 Python이 있습니까?

C #에는 할당하는 동안 쉬운 (짧은) null 검사를 허용 하는 null 병합 연산자 (로 작성 ??)가 있습니다.

string s = null;
var other = s ?? "some default value";

파이썬과 동등한 것이 있습니까?

나는 내가 할 수 있다는 것을 안다.

s = None
other = s if s else "some default value"

그러나 더 짧은 방법이 s있습니까 ( 반복 할 필요가없는 곳 )?



답변

other = s or "some default value"

or운영자가 어떻게 작동 하는지 명확히해야 합니다. 부울 연산자이므로 부울 컨텍스트에서 작동합니다. 값이 부울이 아닌 경우 연산자의 목적으로 부울로 변환됩니다.

점을 유의 or운영자는 반환하지 않습니다 TrueFalse. 대신, 첫 번째 피연산자가 true로 평가되면 첫 번째 피연산자를 리턴하고 첫 번째 피연산자가 false로 평가되면 두 번째 피연산자를 리턴합니다.

이 경우 표현식 x or y은 부울로 변환 될 때 true이거나 true로 평가 x되면 리턴 합니다 True. 그렇지 않으면를 반환합니다 y. 대부분의 경우 C♯의 null-coalescing 연산자와 같은 목적으로 사용되지만 다음을 명심하십시오.

42    or "something"    # returns 42
0     or "something"    # returns "something"
None  or "something"    # returns "something"
False or "something"    # returns "something"
""    or "something"    # returns "something"

당신이 당신의 변수를 사용하는 경우 s중 하나의 클래스의 인스턴스에 대한 참조 또는 보류 뭔가 None(긴 클래스 멤버 정의하지 않는 한 __nonzero__()__len__()), 널 병합 연산자와 같은 의미를 사용하는 것이 안전합니다.

사실, 파이썬의 부작용을 갖는 것이 유용 할 수도 있습니다. 어떤 값이 false로 평가되는지 알고 있으므로이를 사용하여 None구체적으로 (예 : 오류 개체) 사용하지 않고 기본값을 트리거 할 수 있습니다 .

일부 언어에서는이 동작을 Elvis 연산자 라고합니다 .


답변

엄밀히 말하면,

other = s if s is not None else "default value"

그렇지 않으면 s = False될 것입니다 "default value"의도 된 것이 아닐 수있다.

더 짧게 만들려면 다음을 시도하십시오.

def notNone(s,d):
    if s is None:
        return d
    else:
        return s

other = notNone(s, "default value")


답변

다음은 아닌 첫 번째 인수를 반환하는 함수입니다 None.

def coalesce(*arg):
  return reduce(lambda x, y: x if x is not None else y, arg)

# Prints "banana"
print coalesce(None, "banana", "phone", None)

reduce()첫 번째 인수가 아닌 경우에도 모든 인수를 불필요하게 반복 할 수 있으므로이 None버전을 사용할 수도 있습니다.

def coalesce(*arg):
  for el in arg:
    if el is not None:
      return el
  return None


답변

나는 이것이 대답한다는 것을 알고 있지만 객체를 다룰 때 다른 옵션이 있습니다.

다음과 같은 물체가있는 경우 :

{
   name: {
      first: "John",
      last: "Doe"
   }
}

당신이 사용할 수있는:

obj.get(property_name, value_if_null)

처럼:

obj.get("name", {}).get("first", "Name is missing") 

{}“name”이 없으면 기본값으로 추가 하여 빈 오브젝트가 리턴되고 다음 get으로 전달됩니다. 이것은 C #의 null 안전 탐색과 유사 obj?.name?.first합니다.


답변

“또는”의 행동에 대한 Juliano의 답변 외에도 “빠른”

>>> 1 or 5/0
1

때로는 때로는 다음과 같은 것들에 유용한 지름길이 될 수도 있습니다.

object = getCachedVersion() or getFromDB()


답변

또한 단일 값에 대한 @Bothwells 응답 (내가 선호하는)에 추가하여 함수 반환 값의 null 확인을 위해 새로운 walrus-operator를 사용할 수 있습니다 (python3.8부터).

def test():
    return

a = 2 if (x:= test()) is None else x

따라서, test함수 (같이 두 번 계산 될 필요가 없다 a = 2 if test() is None else test())


답변

다음과 같은 둘 이상의 null 병합 작업을 중첩해야하는 경우 :

model?.data()?.first()

이것은 쉽게 해결되는 문제가 아닙니다 or. .get()사전 유형이나 이와 유사한 것을 요구하거나 (어쨌든 중첩 될 수없는) 또는 해결할 수 없습니다.getattr() NoneType에 속성이없는 경우 예외가 발생 .

언어에 null 병합을 추가하는 것을 고려한 관련 pip는 PEP 505 이며 문서와 관련된 토론은 python-ideas 스레드에 있습니다.