레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시

2021년 6월 20일 일요일

[파이썬] 함수에서 결과값을 반환시키는 return 키워드

호출한 함수 내부에서 어떤 처리를 한후 그 결과값을 반환하기 위해 사용하는 것이 return 키워드입니다.

 

Return 키워드의 일반적인 사용은 아래와 같습니다.

 

return [expression_list]

 

return문에서 특정 값이나 수식이 있으면 계산되어 반환되고 그렇지 않으면 “None”이 반환됩니다.

 

return문은 표현식 목록 (또는 None)을 반환 값으로 사용하여 현재 함수 호출을 종료합니다.

 

return문이 finally 문이 있는 try 문에서 제어를 전달하면 해당 finally 문이 실제로 함수를 떠나기 전에 실행됩니다.

 

아래는 실제 사용예입니다.

 

def double (a):

 

    cal = a * a

 

    return cal

 

res = double (5)

 

print ("Result is ", res)

 

함수 double에서 어떤 값의 제곱을 계산한후 반환되어 res라는 변수에 저장됩니다.

 

아래는 실행 결과입니다.

 

Result is  25

 

함수의 반환값을 변수에 저장하지 않고 바로 print문에서 사용할 수도 있습니다.

 

def double (a):

 

    cal = a * a

 

    return cal

 

print ("Result is ", double (5))

 

실행 결과는 위와 동일합니다.

 

Result is  25

 

아래와 같이 return문에 아무런 값을 반환하지 않고 사용할 수도 있습니다.

 

def double (a):

 

    global res

 

    res = a * a

 

    return

 

res = 0

 

double(5)

 

print ("Result is ", res)

 

위에서 함수내에서 전역변수의 값을 직접 계산된 값으로 변경합니다.

 

실행 결과는 위와 동일합니다.

 

Result is  25

 

2021년 6월 17일 목요일

[파이썬] 디버깅을 유용하게 해주는 assert 키워드

assert문은 디버깅 목적을 위해서 프로그램에 삽입하여 사용합니다.

 

일반적인 사용은 아래와 같습니다.

 

assert expression ["," expression]

 

단순한 형태의 assert문은 아래와 같으며,

 

assert expression

 

이는 아래 코드와 동일합니다.

 

if __debug__:

    if not expression: raise AssertionError

 

조금더 확장된 형태의 assert문은 아래와 같으며

 

assert expression1, expression2

 

아래 코드와 같습니다.

 

if __debug__:

    if not expression1: raise AssertionError(expression2)

 

아래 간단한 예제를 보시면

 

rate = 0.9

 

assert 0.0 <= rate <= 1.0

 

print ("Rate is correct range.")

 

rate = 1.1

 

assert 0.0 <= rate <= 1.0

 

print ("Rate is out of range.")

 

첫번째 assert문에서 rate의 값이 범위내에 있으므로 assert 자체가 True가 되어 다음 코드로 넘어갑니다. 하지만 두번째 assert문에서는 범위를 벗어나므로 아래와 같이 AssertionError가 발생됩니다.

 

Rate is in range.

Traceback (most recent call last):

  File "assert_test1.py", line 9, in <module>

    assert 0.0 <= rate <= 1.0

AssertionError

 

단순히 AssertionError만 발생하면 어떤 이유인지 어느 assert문에서 발생했는지를 모르기 때문에 아래와 같이 많이 사용합니다.

 

rate = 1.1

 

assert 0.0 <= rate <= 1.0, "Out of range"

 

print ("Rate is out of range.")

 

그러면 아래와 같이 어떤 AssertionError인지를 명확히 알고 디버깅을 할 수 있습니다.

 

Traceback (most recent call last):

  File "assert_test1.py", line 9, in <module>

    assert 0.0 <= rate <= 1.0, "Out of range"

AssertionError: Out of range

 

AssertionError가 발생이 되면 파이썬 프로그램이 바로 중지되기 때문에 try-except문과 같이 사용하여 에러처리를 해주는 것이 좋습니다.

 

 

try:

 

    rate = 1.1

 

    assert 0.0 <= rate <= 1.0, "Out of range"

 

except AssertionError as err:

 

    print(err)   # print assert expression

 

    rate = rate * 0.5

 

    print ("Rate is adjusted under 1.0")

 

그러면 아래와 같이 에러처리까지 깔끔하게 진행시킬 수가 있습니다.

 

Out of range

Rate is adjusted under 1.0

 

[파이썬] 변수 개체를 삭제하는 del 키워드

del 키워드를 이용해서 변수와 객체의 연결을 끊을 수 있습니다.

 

del 키워드는 다음과 같이 사용가능합니다.

 

del target_list

 

변수를 삭제하면 변수가 동일한 코드 블록의 전역문에서 발생하는지 여부에 따라 로컬 또는 전역에서 해당 변수의 바인딩이 제거됩니다. 변수가 삭제된후 참조를 하게 되면 NameError 에러가 발생합니다.

 

아래 코드를 참조하면 됩니다.

 

a = 10

 

print (a)

 

del a

 

print (a)

 

실행결과는 처음 print문에서는 변수 a의 값이 제대로 나오지만 두번째 print문에서는 에러가 발생됨을 알 수 있습니다.

 

10

Traceback (most recent call last):

  File "del_test1.py", line 7, in <module>

    print (a)

NameError: name 'a' is not defined

 

그런데 아래 코드와 같이 로컬에서 global로 선언한 변수를 삭제하면 어떻게 되는지를 보면

 

count = 10

 

def test (a):

    global count

 

    count = count + a

    print (count)

 

    del count

 

test (100)

 

print (count)

 

첫번째 print문에서는 이상없이 값을 출력되지만 역시 마찬가지로 NameError 에러가 발생됨을 볼 수 있습니다.

 

110

Traceback (most recent call last):

  File "del_test2.py", line 13, in <module>

    print (count)

NameError: name 'count' is not defined

 

마찬가지로 nonlocal로 선언된 변수를 삭제하면 바로 위의 함수에서 참조를 하면 NameError 에러가 발생됩니다.

 

2021년 6월 15일 화요일

[파이썬] 로컬변수가 아님을 선언하기 위한 nonlocal 키워드

nonlocal 문은 전역변수을 제외한 바로 위의 함수에서 사용되는 변수와 바인딩되어 참조하도록 합니다.

 

, nonlocal 문으로 선언되는 변수는 전역변수와 바인딩을 할 수 없습니다.

 

a = 10

 

def test1 ():

    nonlocal a

 

    a = 100

    print (a)

 

test1()

 

print (a)

 

위의 코드를 실행하면 아래와 같이 에러가 발생됨을 알 수 있습니다.

 

File "nonlocal_test1.py", line 4

    nonlocal a

    ^

SyntaxError: no binding for nonlocal 'a' found

 

사용된 함수 바로 한단계 바깥쪽에 위치한 변수와 바인딩을 할 수 있도록 코드를 수정하면

 

a = 10

 

def test1 ():

 

    a = 100

 

    def test2 ():

        nonlocal a   # test1() 함수에 영향을 미침

 

        a = 1000

 

    test2 ()

    print (a)

 

test1 ()

print (a)

 

Test2() 함수에서 nonlocal을 선언했으므로 test1() 함수의 a 변수의 값이 100에서 1000으로 변경됩니다.

 

실제 실행예를 보면, test2() 함수의 값이 1000이 출력되고, 나중에 전역변수의 값인 10이 출력됨을 알 수 있습니다.

 

1000

10

 

2021년 6월 14일 월요일

[파이썬] 로컬에서 전역변수를 사용하기 위한 global 키워드

global 문은 현재 코드 블록 전체에 영향을 미치는 선언문입니다. 이는 명시된 변수가 전역으로 해석된다는 것입니다.

 

global 문은 로컬에서의 사용을 위해서 해당 변수를 global로 선언하여 사용할 수 있는 편리함을 주지만, 그렇다고 너무 남용하면 코드에 혼란을 줄 수 있기 때문에 남용하면 좋지 않습니다.

 

일반적인 사용법에 대한 코드는 아래와 같습니다.

 

def test (a):

    global count

 

    count = count + a

    print (count)

 

count = 10

 

test (100)

 

위에서 test라는 함수내부에서 count라는 전역변수를 사용하기 위해 global 키워드로 선언합니다. 그러면 전역변수를 로컬에서 사용할 수 있습니다.

 

위의 코드의 실행결과로는 “110”이 출력됩니다.

 

2021년 5월 21일 금요일

[파이썬] 전역 변수들의 상태 등을 보여주는 globals() 함수

 

특정 모듈내에서 사용되는 전역 변수들의 변수 이름 및 현재 값 등을 알고 싶을 때 사용하는 함수가 바로 globals()라는 파이썬 빌트인 함수가 있습니다.

 

def test():

    a = 1

    b = 2

    print ("Local Variables in test function")

    print(locals())

 

test()

 

c = 3

b = 4

 

print ("Global Variables in this module")

print (globals())

 

위의 코드에서 locals 함수는 test 함수내의 로컬 변수의 이름과 현재 값을 출력하며, globals 함수는 이 코드내의 전역 변수의 이름과 현재 값을 출력하여 보여줍니다.

 

Local Variables in test function

{'a': 1, 'b': 2}

 

Global Variables in this module

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0368AF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'globals_test1.py', '__cached__': None, 'test': <function test at 0x037EAFA0>, 'c': 3, 'b': 4}

 

이전에 올린 locals 함수와 마찬가지로 globals 함수도 dict 데이터형으로 전역 변수들의 이름과 현재 값을 출력합니다. 실제 사용하는 변수외에 다른 부분들이 같이 나오는데, 이것들은 시스템에서 사용하는 전역변수들입니다.

 

그래서 아래 코드와 같이 전역 변수의 값을 변경하거나 추가하는 코드를 실행해보도록 하겠습니다.

 

c = 3

b = 4

 

print ("Global Variables in this module")

print (globals())

 

globals()['c'] = 13

 

print ("Global Variables in this module after changing values")

print (globals())

 

globals()['d'] = 14

 

print ("Global Variables in this module after adding variable and value")

print (globals())

 

그리고 이 코드의 실행결과는 아래와 같습니다.

 

Global Variables in this module

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0336AF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'globals_test2.py', '__cached__': None, 'c': 3, 'b': 4}

 

Global Variables in this module after changing values

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0336AF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'globals_test2.py', '__cached__': None, 'c': 13, 'b': 4}

 

Global Variables in this module after adding variable and value

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0336AF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'globals_test2.py', '__cached__': None, 'c': 13, 'b': 4, 'd': 14}

 

두번째 실행결과를 보면 locals 함수와는 다르게 globals 함수를 사용하여 전역변수의 값이 3에서 13으로 변경가능함을 볼 수 있습니다.

 

그리고 마찬가지로 globals 함수를 사용하여 새로운 전역변수 추가도 가능함을 볼 수 있습니다.