ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] False,True 관련 연산자 동작(+None)
    Python 2022. 1. 7. 18:56

    1. 값 비교에서 True는 1, False는 0값을 가진다.

    2. Falsy 와 Truthy 용어

    3. Built-in bool() 함수

    4. 객체를 Truthy 또는 Falsy 로 만들기

    5. __len__() 메서드

    6. 논리 연산자의 단락 평가

    7. None


    1. 값 비교에서 True는 1, False는 0값을 가지게 설계되어있다.

     

    is 연산자는 객체 비교 연산자이고, == 연산자는 값 비교 연산자이다.

    값 비교 연산자인 ==에서 True, False가 사용될 때 True는 1, False는 0값을 가진다.

     

    • True는 1값을 가진다
    print(-1 == True)
    print(0 == True)
    print(1 == True) #True는 값으로 1로 간주됨

     

    구글링 하다 파이썬은 operator overloading을 지원하는 언어임을 알았다.

    == 연산자에 해당하는 메서드는  __eq__이다. 

    class Test:
    
        def __init__(self, value):
            self.value = value
    
        def __eq__(self, other):
            if self.value == other.value:
                return True
            else:
                return False
    
    
    a = Test(3)
    b = Test(4)
    print(a == b) # 아래의 메서드와 같음
    print(a.__eq__(b))

     

     

    아래의 첫줄은 float의 __eq__메서드가 호출될 것이고, 두번째줄은 int의 __eq__메서드가 호출될 텐데 1.0이나 1이나 같게 메서드들이 설계되어있음을 확인하였다.

    print(1.0 == 1)
    print(1 == 1.0)

     

    • False는 0값을 가진다.
    print(-1 == False)
    print(0 == False)
    print(1 == False)

     

    또한 0.0과 0의 값 비교는 True를 리턴하게 설계되어있다.

    print(0.0 == 0)
    print(0 == 0.0)

     

    정리하면 다음과 같이된다. 

    print(True == False)
    # print(1==0)
    
    print(True == True)
    # print(1==1)
    
    print(False == False)
    # print(0==0)

     

    간단 테스트

    if (1 == False) == False:
        print('True')
    else:
        print('false')

     

    값 비교 문맥에서 True, False가 값으로 계산되는 것을 확인하였다.

    밑에서 살펴볼 내용은 반대로 값,변수,객체가 True, False로 취급되는 것을 확인한다.


    2. Falsy 와 Truthy 용어

    https://www.freecodecamp.org/news/truthy-and-falsy-values-in-python/

     

    Truthy and Falsy Values in Python: A Detailed Introduction

    WelcomeIn this article, you will learn: What truthy and falsy values are.What makes a value truthy or falsy.How to use the bool() function to determine if a value is truthy or falsy.How to make objects from user-defined classes truthy or falsy using the sp

    www.freecodecamp.org

    Truthy - 사실은 아니지만 사실 같은

    Falsy - 거짓이 아니지만 거짓 같은

     

    - Truthy 값이면 True로 평가된다.

    - Falsy 값이면 False로 평가된다.

     

    if문 while문의 조건식을 불린이 평가되는 Boolean Context라고 한다.

    Boolean Context에는 표현식 대신 변수, 값, 객체가 사용될 수 있다.

     

    파이썬에서는 모든 객체는 / if문 while문의 조건에 / truthy 테스트에 사용될 수 있다. 

    https://docs.python.org/3/library/stdtypes.html#truth-value-testing

     

    Built-in Types — Python 3.10.1 documentation

    The following sections describe the standard types that are built into the interpreter. The principal built-in types are numerics, sequences, mappings, classes, instances and exceptions. Some collection classes are mutable. The methods that add, subtract,

    docs.python.org

     

    어떤 값이 Falsy 와 Truthy 인가

    Falsy vlaue

     

    • sequence and collection

     

    빈 리스트 []

    빈 튜플 ()

    빈 딕셔너리 {}

    빈 셋 set()

    빈 스트링 ""

    빈 range 객체 range(0)

    if []:
        print(True)
    else:
        print(False)
    
    if ():
        print(True)
    else:
        print(False)
    
    if {}:
        print(True)
    else:
        print(False)
    
    if set():
        print(True)
    else:
        print(False)
    
    if "":
        print(True)
    else:
        print(False)
    
    if range(0):
        print(True)
    else:
        print(False)

     

    • number

     

    모든 숫자형 0

    정수 0

    실수 0.0

    복소수 0j

    if 0:
        print(True)
    else:
        print(False)
    
    if 0.0:
        print(True)
    else:
        print(False)
    
    if 0j:
        print(True)
    else:
        print(False)

     

    • constant

     

    None

    False (Falsy값이 아닌 real False이지만 그냥 넣어놓음)

    if None:
        print(True)
    else:
        print(False)


    Truthy value

    -- default 로 객체는 True로 간주된다.

    class Test:
        pass
    
    
    if Test():
        print(True)
    else:
        print(False)

    -- 위에서 설명한 것들 제외한 모든 것

    -- True (Truthy가 아닌 read True이지만 넣어놓음)

     

     

    위의 모든 코드에서는 조건에 해당하는 Boolean Context에 값을 사용했지만 값 대신 변수를 사용할 수 있다.


    3. Built-in bool() 함수

     

    bool() 함수를 사용하여 객체( 값(리터럴)도 객체 )가 Falsy인지 Truthy인지 확인할 수 있다. (파이썬은 모든 것이 객체)

    class Test:
        pass
    
    
    print(bool(0))
    print(bool(0.0))
    print(bool(range(0)))
    test = Test()
    print(bool(test))


    4. 객체를 Truthy 또는 Falsy 로 만들기

     

    객체의 Truthy, Falsy를 판별하는데는 __bool__() , __len__() 두 메서드가 사용된다.

    default로 두 메서드가 정의되어있지 않기 때문에 Truthy로 판별된다.

     

    bool() 내장함수는 -> __bool__(), __len__() 확인하여 Truthy, Falsy 확인

     

    __bool__() 메서드는 리턴값이 항상 True, False 여야한다.

    __len__() 메서드의 low 레벨 동작을 잘모르겠지만 리턴값은 0포함 양의 정수로 나타내질 수 있어야 한다.

    (True, False도 1,0값을 가지기 때문에 리턴에는 사용될 수 있긴 하다)

     

    5. 이번 포스팅에 관한 내용은 아니지만 len() 내장함수는 -> __len__() 확인하여 길이 리턴

    주제를 잠깐 벗어나서 len() 내장함수를 확인하면

    class Test:
    
        def __init__(self, value):
            self.value = value
    
        def __len__(self):
            return self.value
    
    
    three = Test(3)
    print(len(three))
    
    zero = Test(0)
    print(len(zero))
    
    minus = Test(-3)
    print(len(minus)) #에러

    False는 0, True는 1

    class Test:
    
        def __init__(self, value):
            self.value = value
    
        def __len__(self):
            return self.value
    
    
    t = Test(True)
    print(len(t))
    
    f = Test(False)
    print(len(f))

     

    다시 본론으로 넘어오자.

     

    두 메서드가 모두 정의되어 있는 경우 __bool__() 메서드의 리턴값을 우선으로 확인하여 Truthy, Falsy를 판단한다.

    __bool__() 메서드가 정의되어 있지 않은 경우에는  __len__() 메서드의 리턴값을 확인하여 Truthy, Falsy를 판단한다. 

     

     

    __bool__() - 인스턴스 변수 value가 0이상이면 Truthy

    class Test:
    
        def __init__(self, value):
            self.value = value
    
        def __bool__(self):
    
            # value 가 0 이상이면 Truthy
    
            if self.value >= 0:
                return True
            else:
                return False
    
        def __len__(self):
            # return 0 -> Falsy 이지만 __bool__ 메서드가 정의 되어 있어 무시됨
            return 0
    
    
    t = Test(10)
    print(bool(t))
    
    t2 = Test(-10)
    print(bool(t2))

    __bool__()메서드가 정의되어 있지 않으면 __len__()메서드가 확인된다. __len__()메서드 또한 없으면 default로 Truthy로 판별된다.


    6. 논리 연산자의 단락 평가

     

    파이썬의 논리 연산자에 해당하는 or, and, not은 boolean context이다. 즉 모든 값들을 True, False로 변경하여 논리 연산이 진행된다.

     

    코드를 보자. 0 이외의 값은 Truthy값이였다. 그렇기 때문에 3은 True로 평가가 되어 or False는 평가가 되지 않는다.

    if 3 or False:
        print(True)
    else:
        print(False)
    
    #다음과 같이 변경됨
    if 3:
        print(True)
    else:
        print(False)
        
    #다음과 같이 변경됨
    if True:
        print(True)
    else:
        print(False)

    조건식인 boolean context에서의 단락 평가는 문제가 없다. 자동으로 결과가 True, False불린으로 변경되어 참 거짓에 따라 수행할 코드가 수행되기 때문이다.

     

    그렇지만 출력과 리턴의 경우 주의해야한다.

    논리 연산자의 단락 평가시 마지막에 평가된 것이 True,False가 아닌 객체인 경우 객체가 출력된다.

    print(3 or True) #True가 아님

    단락평가가 되어 마지막에 평가된 3이 True로 변경되어 True로 출력될 것 같지만, 그렇지 않고 단락 평가된 마지막 것의 값이 그대로 리턴된다.

     

    print(3 and 10 and 7)

     

    print(3 and 10 and 0)

     

    print(False or '')

    빈 문자열이라 아무것도 출력되지 않는다.

     

    이러한 결과는 메서드나 함수에 적용해보면 결과가 달라지기 때문에 주의해야 한다.

    def test():
        return 3 or True
    
    
    result = test()
    print(type(result))

    def test():
        return True or 3
    
    
    result = test()
    print(type(result))

    def test():
        return True and 3 and [1,2,3]
    
    
    result = test()
    print(type(result))


    7. None

    None에 대해 알아보고 앞에서 다뤘던 연산자 예제를 더 살펴본다.

     

    https://www.educative.io/edpresso/what-is-the-none-keyword-in-python

     

    What is the None keyword in Python?

    Creator: Edpresso Team

    www.educative.io

     

    None 상수

    https://www.educative.io/edpresso/what-is-the-none-keyword-in-python

     

    파이썬의 변수에 None 키워드를 사용하여 대입하면

    NoneType 클래스의 객체가 최초에 생성되고 변수는 이 객체를 가리킨다.

    def info(obj):
        print('id:', id(obj))
        print('type:', type(obj))
        print('print:', obj)
        print()
    
    
    none_type = None
    info(none_type)

     

    파이썬의 immutable 객체는 싱글톤으로 같은 객체를 참조한다.

    NoneType 또한 immutable 객체로 이후에 변수에 None키워드를 사용하여 대입하면 이전에 만들어진 NoneType 객체를 참조하게 된다.

    def info(obj):
        print('id:', id(obj))
        print('type:', type(obj))
        print('print:', obj)
        print()
    
    
    none_type = None
    info(none_type)
    
    none_type2 = None
    info(nonw_type2)

     

    None 용도

    변수에 None 키워드를 사용하여 NoneType 객체를 가리키게 하는 것은, 이 변수가 아직 의미있는 값으로 초기화되지 않은 상태라는 용도로 활용된다.

    a = None
    # 코드들이 있다고 가정
    if a is None:
        print('a 변수 활용 못함...')
    else:
        print('a 변수를 가지고 활용 하는 코드들')

     

    함수, 메서드의 인자에 값이 대입되지 않음

    def calculation(a, b, operation=None):
        if operation is None:
            print('연산 인자 값이 설정 되지 않음')
        elif operation == '+':
            print(a + b)
        elif operation == '-':
            print(a - b)
        elif operation == '*':
            print(a * b)
        elif operation == '/':
            print(a / b)
    
    
    calculation(7, 5)
    # 어떠한 산술 연산인지 대입되지 않음

     

    함수, 메서드가 리턴하는 것이 없을 때

    def test_function():
        pass
    
    
    def test_function2():
        return
    
    
    a = test_function()
    print(a)
    print()
    
    b = test_function2()
    print(b)

     

    None 을 연산자에 사용

     

    일단 is 연산자는 객체비교이기 때문에 자기 자신인 None 객체이외의 객체 비교는 모두 False이다.

    a = None
    print(None is None)
    print(a is None)

    이외에는 모두 False이다.

     

     

    객체의 Truthy,Falsy를 확인하는 bool()함수로

    NoneType 인스턴스인 None객체의 Truthy,Falsy를 확인해보면 False이다.

    print(bool(None))

    그렇기 때문에 값을 True,False로 바꾸는 boolean context에서 None이 사용되면 False 결과가 나온다.

    if None:
        print(True)
    else:
        print(False)


    == 연산자 사용시 None은 값을 가지고 있지 않기 때문에 다른 것들과 비교할 수 없고, 자기 자신인 None만 비교할 수 있다. 자기 자신과 비교하는 경우 이외에는 항상 False 이다.

     

    == 연산자에서 True, False는 1,0을 가진다.

    print(None == None)
    
    print(None == True)
    # print(None == 1)
    
    print(None == False)
    # print(None == 0)
    
    print(None == -100)

    None의 ==연산자에 해당하는 메서드는 None이외에 비교가 불가능해 False를 리턴하게 설계되어있을 것이다.

    삽집하게 된 원인인데 ==은 boolean context가 아니다. 값을 불린으로 변경하는 boolean context로 착각해버려 다음과 같이 생각해버렸다.

    print(None == False)
    # Boolean Context가 아니라서 밑의 코드가 아님
    print(False == False)

    논리 연산자

     

    논리 연산자는 boolean context였다. 값,변수,객체를 True,False로 처리하게 된다.

    bool() 내장함수를 통해 NoneType 객체인 None을 확인 하였을 때 Falsy이기 때문에 False를 가지는 것을 확인하였다.

    if None or None:
        print(True)
    else:
        print(False)

     

    위에서 살펴본 논리 연산자의 단락평가의 출력 개념을 다시 확인해보자.

    print(None and False)
    print(None and True)

    None은 Falsy라 False로 앞부분의 표현식에서 and 결과를 예상할 수 있다. 단락평가된 것이 NoneType객체인 None이므로, False 대신 None이 출력된다.

     

    print(None and 1)
    print(None and True)
    print(None and False)
    print(None and 0)
    print(None and 'f')
    print(None and '')

    print('d' and None)
    # True and False
    # 후자는 객체이므로 False대신 None 출력

     

    논리 연산자의 객체그대로 출력된다는 것을 알지 못했을때 출력 결과를 이해하지 못해서 좀 헤맸었다.

    'Python' 카테고리의 다른 글

    [NumPy] Broadcasting  (0) 2022.01.23
    [Python] list comprehension  (0) 2022.01.20
    [Python] 클래스 상속과 super()함수의 동작이해  (1) 2022.01.12
    [Python] 클래스 기초  (0) 2022.01.11
    [Python] immutable, mutable 객체  (0) 2022.01.06

    댓글

Designed by Tistory.