Development language/Python

Python-8. Module이란? / 모듈의 기본 사용법(import, from)

DOT-ICD 2021. 11. 25. 22:37
728x90

프로그래머가 처음부터 끝까지 프로그램의 모든 것을 작성하기에는 굉장히 어렵고 시간이 오래걸리는 일이다.

그렇다면, 미리 자주 사용되는 함수와 같은 기능들을 수학공식 만들 듯 미리 작성하고, 이름만 따와서 사용할 수 있다면 어떨까?

(우리는 적분 공식을 사용할 때, 구분구적법에서부터 시작하여 적분하지 않는다! 미리 구분구적법을 통해 알아본 결과들을 외우고, 이를 바탕으로 계산한다. 그것이 효율적이기 때문에!)

 

Q. Modules?

앞서말한 적분공식을 외워 적분문제를 푸는 것처럼, python개발자들은 미리 module이라는 객체의 형태를 만들고, 그 객체안에 자주 사용되는 함수들과 변수들의 구조와 작동원리를 미리 프로그래밍해놓는다.

아래의 링크는 python(v.3.9.0)이 기본적으로 지원하는 모듈들에 대해 정리가 된 온라인 문서이다. 

https://docs.python.org/release/3.9.0/py-modindex.html 

 

Python Module Index — Python 3.9.0 documentation

numbers Numeric abstract base classes (Complex, Real, Integral, etc.).

docs.python.org

그 결과 우리는 모듈의 이름과 그 안에 적혀있는 함수또는 변수의 이름, 매개변수의 개수와 반환값의 형태만 안다면 원하는 기능을 구현할 수 있다. 

아래의 예를 보면서 이 말을 이해해보자.

import math

print(math.sin(math.pi))

실행결과
1.2246467991473532e-16
->0에 가까운 수가 출력된 것을 확인할 수 있다. 그러나 0이 출력되지는 않았다! 이건 나중에 알아보자

sin(pi)의 값을 계산하기 위해, math라는 모듈에서 sin함수를 가져오고, pi라는 변수를 가져왔다.

이를 인터프리터에 전달하기 위한 방법으로 모듈이름.함수 또는 모듈이름.객체 의 형태를 사용하는 것이다!

math.sin은 math모듈에서 sin함수를 가져와 사용한다는 의미이고, math.pi는 math모듈에서 pi변수를 가져와 사용한다는 의미이다.

이제 모듈을 불러오는 방법과 사용하는 방법에 대해 더 자세히 알아보자.


우선, Python에서 지원하는 함수들과 모듈의 함수의 차이를 생각해보자!


Built-in function

python에 미리 내장되어 있을 정도로 자주 사용되고 가벼운 함수들이다.

예로, print함수, abs함수 등이 있다. 이를 통해 알 수 있듯 정말 필수적인 함수들만이 python에 미리 내장되어있다.

이 함수들을 사용하기 위해서 어떤 모듈도 import할 필요가 없다. (이전까지의 포스트에서 단 한번도 import를 통해 다른 모듈을 불러온 적이 없다.) 그냥 사용하면 인터프리터가 잘 해석하여 동작시켜준다.


Module function

그렇다면 왜 모듈에 포함된 모든 함수들을 미리 python에 내장하지 않을까? 프로그램을 작성할 때마다 필요한 모듈을 찾고 불러오는 일은 귀찮은 일이 아닌가?

그 이유는 당연하게도 자원이 한정적이기 때문이다. 미리 내장되어있는 함수가 많아질수록, python이라는 언어를 동작시키는 것에 더욱 많은 시스템 자원이 소모된다. 따라서, 개발자들이 자신들이 필요한 함수만을 사용하여 시스템 자원을 아끼며 사용할 수 있도록 모듈 이라는 개념이 만들어진 것이다.


Import

이제 내장함수와 모듈함수의 차이점을 알아보았다. 그렇다면 어떻게 모듈 속에 작성되어있는 함수를 사용할 수 있을까?

앞에서 보여준 간단한 예시에서 import math 라는 이전에 보지 못한 새로운 코드가 포함되어 있다. 이 과정을 모듈을 임포트한다고 한다. 

간단히 말해서 모듈을 불러오는 것이다.

모듈들은 python 인터프리터에 내장되어 있는 것이 아니다. (무작정 사용하려고 하면 인터프리터가 해석하지 못한다는 말이다.)

따라서, 이 모듈들을 사용하겠다고 미리 인터프리터에 알려주어야 하고, 이를 통해 그 모듈이 담고있는 여러가지 함수와 변수들을 가져와 준비시켜야 한다. 이를 위해 import 함수를 사용한다.

사용법은 간단하다. import 모듈명 이다.

import math
import numpy

위와 같이 모듈들을 불러올 수 있다.


Using Module's functions and variables

math모듈을 예로 들어 설명해보자. 

우선, 인터프리터는 내장함수를 제외한 다른 함수의 이름은 def를 통해 미리 작성된 함수가 아니라면 인식하지 못한다. 따라서, 우리는 사용하고자 하는 함수가 내가 불러온 모듈 속에 있는 함수임을 인터프리터에 알려야 한다. 이를 위해 우리는 일반적으로 모듈이름.함수 또는 모듈이름.변수 형태로 모듈에 포함된 함수와 변수를 사용한다.

아래의 예시를 보자.

import math

print(sin(pi))

실행결과
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    sin(pi)
NameError: name 'sin' is not defined

math라는 모듈을 불러왔고, 그 안의 sin함수를 사용하려 했지만, 인터프리터는 sin함수가 어떤 함수인지 모르겠다고 오류메시지를 띄운다.

이제 아래의 다른 예시를 보자.

import math

print(math.sin(math.pi))

실행결과
1.2246467991473532e-16

sin함수가 math라는 모듈에 속해있다는 점을 math.sin 이라는 형태로 알려주었더니, 인터프리터가 코드를 잘 해석해서 결과를 출력해주었다. pi역시 마찬가지이다. math.pi를 통해 pi라는 변수가 math모듈에 작성되어 있다는 점을 알려주었기 때문에 인터프리터가 해석하고 계산할 수 있었던 것이다.

 

위의 두 예시를 통해 알아본 것처럼, 모듈에 속해있는 어떤 함수나 변수를 사용하기 위해서는 일반적으로 모듈이름.함수 또는 모듈이름.객체 의 형태로 사용해야함을 잊지말자! 

또한, 파이썬 인터프리터는 기본적으로 첫번째 줄의 코드부터 아래로 해석하기 때문에, 사용하고자 하는 모듈을 사용하는 코드보다 앞줄에서 미리 import해야 한다. 

 

 

더보기

*참고

모듈 역시 help 함수의 parameter가 될 수 있다. 이를 통해 math 모듈이 어떤 함수와 변수를 갖고있는지 알아볼 수 있다.

아래의 예시를 보자.

>>> import math
>>> type(math)
Help on built-in module math:

NAME
    math

DESCRIPTION
    This module provides access to the mathematical functions
    defined by the C standard.

FUNCTIONS
    acos(x, /)
        Return the arc cosine (measured in radians) of x.
        
        The result is between 0 and pi.
    
    acosh(x, /)
        Return the inverse hyperbolic cosine of x.
    
    asin(x, /)
        Return the arc sine (measured in radians) of x.
        
        The result is between -pi/2 and pi/2.
    
    asinh(x, /)
        Return the inverse hyperbolic sine of x.
    
    atan(x, /)
        Return the arc tangent (measured in radians) of x.
        
        The result is between -pi/2 and pi/2.
    
    atan2(y, x, /)
        Return the arc tangent (measured in radians) of y/x.
        
        Unlike atan(y/x), the signs of both x and y are considered.
    
    atanh(x, /)
        Return the inverse hyperbolic tangent of x.
    
    ceil(x, /)
        Return the ceiling of x as an Integral.
        
        This is the smallest integer >= x.
    
    comb(n, k, /)
        Number of ways to choose k items from n items without repetition and without order.
        
        Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates
        to zero when k > n.
        
        Also called the binomial coefficient because it is equivalent
        to the coefficient of k-th term in polynomial expansion of the
        expression (1 + x)**n.
        
        Raises TypeError if either of the arguments are not integers.
        Raises ValueError if either of the arguments are negative.
    
    copysign(x, y, /)
        Return a float with the magnitude (absolute value) of x but the sign of y.
        
        On platforms that support signed zeros, copysign(1.0, -0.0)
        returns -1.0.
    
    cos(x, /)
        Return the cosine of x (measured in radians).
    
    cosh(x, /)
        Return the hyperbolic cosine of x.
    
    degrees(x, /)
        Convert angle x from radians to degrees.
    
    dist(p, q, /)
        Return the Euclidean distance between two points p and q.
        
        The points should be specified as sequences (or iterables) of
        coordinates.  Both inputs must have the same dimension.
        
        Roughly equivalent to:
            sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
    
    erf(x, /)
        Error function at x.
    
    erfc(x, /)
        Complementary error function at x.
    
    exp(x, /)
        Return e raised to the power of x.
    
    expm1(x, /)
        Return exp(x)-1.
        
        This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.
    
    fabs(x, /)
        Return the absolute value of the float x.
    
    factorial(x, /)
        Find x!.
        
        Raise a ValueError if x is negative or non-integral.
    
    floor(x, /)
        Return the floor of x as an Integral.
        
        This is the largest integer <= x.
    
    fmod(x, y, /)
        Return fmod(x, y), according to platform C.
        
        x % y may differ.
    
    frexp(x, /)
        Return the mantissa and exponent of x, as pair (m, e).
        
        m is a float and e is an int, such that x = m * 2.**e.
        If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.
    
    fsum(seq, /)
        Return an accurate floating point sum of values in the iterable seq.
        
        Assumes IEEE-754 floating point arithmetic.
    
    gamma(x, /)
        Gamma function at x.
    
    gcd(*integers)
        Greatest Common Divisor.
    
    hypot(...)
        hypot(*coordinates) -> value
        
        Multidimensional Euclidean distance from the origin to a point.
        
        Roughly equivalent to:
            sqrt(sum(x**2 for x in coordinates))
        
        For a two dimensional point (x, y), gives the hypotenuse
        using the Pythagorean theorem:  sqrt(x*x + y*y).
        
        For example, the hypotenuse of a 3/4/5 right triangle is:
        
            >>> hypot(3.0, 4.0)
            5.0
    
    isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)
        Determine whether two floating point numbers are close in value.
        
          rel_tol
            maximum difference for being considered "close", relative to the
            magnitude of the input values
          abs_tol
            maximum difference for being considered "close", regardless of the
            magnitude of the input values
        
        Return True if a is close in value to b, and False otherwise.
        
        For the values to be considered close, the difference between them
        must be smaller than at least one of the tolerances.
        
        -inf, inf and NaN behave similarly to the IEEE 754 Standard.  That
        is, NaN is not close to anything, even itself.  inf and -inf are
        only close to themselves.
    
    isfinite(x, /)
        Return True if x is neither an infinity nor a NaN, and False otherwise.
    
    isinf(x, /)
        Return True if x is a positive or negative infinity, and False otherwise.
    
    isnan(x, /)
        Return True if x is a NaN (not a number), and False otherwise.
    
    isqrt(n, /)
        Return the integer part of the square root of the input.
    
    lcm(*integers)
        Least Common Multiple.
    
    ldexp(x, i, /)
        Return x * (2**i).
        
        This is essentially the inverse of frexp().
    
    lgamma(x, /)
        Natural logarithm of absolute value of Gamma function at x.
    
    log(...)
        log(x, [base=math.e])
        Return the logarithm of x to the given base.
        
        If the base not specified, returns the natural logarithm (base e) of x.
    
    log10(x, /)
        Return the base 10 logarithm of x.
    
    log1p(x, /)
        Return the natural logarithm of 1+x (base e).
        
        The result is computed in a way which is accurate for x near zero.
    
    log2(x, /)
        Return the base 2 logarithm of x.
    
    modf(x, /)
        Return the fractional and integer parts of x.
        
        Both results carry the sign of x and are floats.
    
    nextafter(x, y, /)
        Return the next floating-point value after x towards y.
    
    perm(n, k=None, /)
        Number of ways to choose k items from n items without repetition and with order.
        
        Evaluates to n! / (n - k)! when k <= n and evaluates
        to zero when k > n.
        
        If k is not specified or is None, then k defaults to n
        and the function returns n!.
        
        Raises TypeError if either of the arguments are not integers.
        Raises ValueError if either of the arguments are negative.
    
    pow(x, y, /)
        Return x**y (x to the power of y).
    
    prod(iterable, /, *, start=1)
        Calculate the product of all the elements in the input iterable.
        
        The default start value for the product is 1.
        
        When the iterable is empty, return the start value.  This function is
        intended specifically for use with numeric values and may reject
        non-numeric types.
    
    radians(x, /)
        Convert angle x from degrees to radians.
    
    remainder(x, y, /)
        Difference between x and the closest integer multiple of y.
        
        Return x - n*y where n*y is the closest integer multiple of y.
        In the case where x is exactly halfway between two multiples of
        y, the nearest even value of n is used. The result is always exact.
    
    sin(x, /)
        Return the sine of x (measured in radians).
    
    sinh(x, /)
        Return the hyperbolic sine of x.
    
    sqrt(x, /)
        Return the square root of x.
    
    tan(x, /)
        Return the tangent of x (measured in radians).
    
    tanh(x, /)
        Return the hyperbolic tangent of x.
    
    trunc(x, /)
        Truncates the Real x to the nearest Integral toward 0.
        
        Uses the __trunc__ magic method.
    
    ulp(x, /)
        Return the value of the least significant bit of the float x.

DATA
    e = 2.718281828459045
    inf = inf
    nan = nan
    pi = 3.141592653589793
    tau = 6.283185307179586

FILE
    (built-in)

 


그런데, 매번 모듈이름과 점을 찍는 것은 상당히 귀찮은 일일 수 밖에 없다. 그래서 모듈의 이름을 사용하지 않고 모듈 속의 함수와 변수를 사용하는 몇가지 방법이 존재한다.


1. from 모듈명 import (함수 or 변수 , 함수 or 변수 , 함수 or 변수, ...)

 특정 모듈에서 몇가지의 함수나 변수만을 사용해야 할 경우 이 방식을 사용한다.

아래의 예시를 보자.

from math import pi, sin

print(sin(pi))

실행결과
1.2246467991473532e-16

위의 예시처럼 math.을 sin과 pi에 일일히 붙이지 않아도 오류가 나지 않고, 정상적으로 값이 출력됨을 확인할 수 있다.

2. from 모듈명 import *

특정 모듈의 대부분을 사용해야 하지만, 일일히 모듈이름과 .을 붙이기 귀찮은 경우 사용할 수 있는 방법이다.

이를 통해 해당 모듈에 존재하는 함수와 객체는 모듈명. 을 일일히 붙이지 않고 이름만을 가져와서 사용할 수 있다.

from math import *

print(sin(pi))
print(cos(pi))
실행결과
1.2246467991473532e-16
-1.0

 

3. 주의점

 위의 두가지 방법을 여러가지 모듈을 가져와서 작성하는 복잡한 코드에 작성할 경우 문제가 생길 수 있다.

 예를 들어 생각해보자.  십여가지의 모듈을 가져와서 작성한 딥러닝 코드가 있다고 생각하자.  이 경우 두가지의 문제점이 발생할 수 있다.

 첫째로, 이 코드에서 데이터 전처리에 사용하는 여러가지 모듈 속 수많은 함수들 중에 어느 하나가 문제를 일으켰을 때, 우리가 만약 1, 2와 같은 방법을 사용하여 모듈이름을 명시하지 않았다면 문제를 바로잡는 것이 매우 힘들어진다!

따라서, 간단한 코드를 작성할 경우 1,2의 방법을 사용하는 것이 나쁜 선택이 아니지만, 복잡한 코드를 작성하는 경우 좋은 선택이 아닐 것이다!

둘째로, 만약 모듈 안에 정의되어있는 함수나 변수의 이름이 우연히 일치한다면 그것으로 인해 오류가 날 가능성이 존재한다. 

 

728x90