소개
이 랩에서는 Python 패키지 구성과 관련된 중요한 개념을 배우게 됩니다. 먼저, Python 모듈에서 __all__을 사용하여 내보낼 심볼을 제어하는 방법을 배우게 됩니다. 이 기술은 모듈에서 노출되는 내용을 관리하는 데 매우 중요합니다.
둘째, 하위 모듈을 결합하여 더 간단한 임포트를 수행하는 방법과 더 나은 코드 구성을 위해 모듈 분할 기술을 익히게 됩니다. 이러한 실습은 Python 코드의 가독성과 유지 관리성을 향상시킬 것입니다.
패키지 임포트 복잡성 이해
Python 패키지 작업을 시작하면 모듈을 임포트하는 것이 상당히 복잡하고 장황해질 수 있다는 것을 빠르게 깨닫게 될 것입니다. 이러한 복잡성은 코드를 읽고 쓰기 어렵게 만들 수 있습니다. 이 랩에서는 이 문제에 대해 자세히 살펴보고 임포트 프로세스를 단순화하는 방법을 배우겠습니다.
현재 임포트 구조
먼저, 터미널을 열어보겠습니다. 터미널은 컴퓨터의 운영 체제와 상호 작용할 수 있는 강력한 도구입니다. 터미널이 열리면 프로젝트 디렉토리로 이동해야 합니다. 프로젝트 디렉토리는 Python 프로젝트와 관련된 모든 파일이 저장되는 곳입니다. 이를 위해 "change directory"를 의미하는 cd 명령을 사용합니다.
cd ~/project
이제 프로젝트 디렉토리에 있으므로 structly 패키지의 현재 구조를 살펴보겠습니다. Python 에서 패키지는 관련 모듈을 구성하는 방법입니다. ls -la 명령을 사용하여 숨겨진 파일을 포함하여 structly 패키지 내의 모든 파일과 디렉토리를 나열할 수 있습니다.
ls -la structly
structly 패키지 내에 여러 Python 모듈이 있는 것을 확인할 수 있습니다. 이러한 모듈에는 코드에서 사용할 수 있는 함수와 클래스가 포함되어 있습니다. 그러나 이러한 모듈의 기능을 사용하려면 현재 긴 임포트 문을 사용해야 합니다. 예를 들어:
from structly.structure import Structure
from structly.reader import read_csv_as_instances
from structly.tableformat import create_formatter, print_table
이러한 긴 임포트 경로는 특히 코드에서 여러 번 사용해야 하는 경우 작성하기 번거로울 수 있습니다. 또한 코드를 덜 읽기 쉽게 만들며, 이는 코드를 이해하거나 디버깅하려는 경우 문제가 될 수 있습니다. 이 랩에서는 이러한 임포트를 더 간단하게 만드는 방식으로 패키지를 구성하는 방법을 배우겠습니다.
패키지의 __init__.py 파일의 내용을 먼저 살펴보겠습니다. __init__.py 파일은 Python 패키지에서 특별한 파일입니다. 패키지가 임포트될 때 실행되며, 패키지를 초기화하고 필요한 임포트를 설정하는 데 사용할 수 있습니다.
cat structly/__init__.py
__init__.py 파일이 비어 있거나 코드가 거의 없는 것을 발견할 수 있습니다. 다음 단계에서는 임포트 문을 단순화하기 위해 이 파일을 수정합니다.
목표
이 랩이 끝나면 훨씬 더 간단한 임포트 문을 사용할 수 있게 되는 것이 목표입니다. 앞에서 본 긴 임포트 경로 대신 다음과 같은 문을 사용할 수 있습니다.
from structly import Structure, read_csv_as_instances, create_formatter, print_table
또는 다음과 같이 사용할 수도 있습니다.
from structly import *
이러한 더 간단한 임포트 문을 사용하면 코드가 더 깔끔해지고 작업하기 쉬워집니다. 또한 코드를 작성하고 유지 관리할 때 시간과 노력을 절약할 수 있습니다.
__all__을 사용하여 내보낼 심볼 제어
Python 에서 from module import * 문을 사용할 때 모듈에서 어떤 심볼 (함수, 클래스, 변수) 을 임포트할지 제어하고 싶을 수 있습니다. 이럴 때 __all__ 변수가 유용합니다. from module import * 문은 모듈의 모든 심볼을 현재 네임스페이스로 임포트하는 방법입니다. 그러나 때로는 모든 심볼을 임포트하고 싶지 않을 수 있습니다. 특히 심볼이 많거나 일부 심볼이 모듈 내부에만 사용되도록 의도된 경우입니다. __all__ 변수를 사용하면 이 문을 사용할 때 정확히 어떤 심볼을 임포트해야 하는지 지정할 수 있습니다.
__all__이란 무엇인가?
__all__ 변수는 문자열의 리스트입니다. 이 리스트의 각 문자열은 from module import * 문을 사용할 때 모듈이 내보내는 심볼 (함수, 클래스 또는 변수) 을 나타냅니다. 모듈에 __all__ 변수가 정의되어 있지 않으면 import * 문은 밑줄로 시작하지 않는 모든 심볼을 임포트합니다. 밑줄로 시작하는 심볼은 일반적으로 모듈에 대한 private 또는 internal 로 간주되며 직접 임포트하도록 되어 있지 않습니다.
각 하위 모듈 수정
이제 structly 패키지의 각 하위 모듈에 __all__ 변수를 추가해 보겠습니다. 이렇게 하면 from module import * 문을 사용할 때 각 하위 모듈에서 어떤 심볼이 내보내지는지 제어하는 데 도움이 됩니다.
- 먼저,
structure.py를 수정해 보겠습니다.
touch ~/project/structly/structure.py
이 명령은 프로젝트의 structly 디렉토리에 structure.py라는 새 파일을 만듭니다. 파일을 만든 후 __all__ 변수를 추가해야 합니다. 파일 맨 위, 임포트 문 바로 뒤에 이 줄을 추가합니다.
__all__ = ['Structure']
이 줄은 누군가 from structure import *를 사용할 때 Structure 심볼만 임포트하도록 Python 에 지시합니다. 파일을 저장하고 편집기를 종료합니다.
- 다음으로,
reader.py를 수정해 보겠습니다.
touch ~/project/structly/reader.py
이 명령은 structly 디렉토리에 reader.py라는 새 파일을 만듭니다. 이제 파일에서 read_csv_as_로 시작하는 모든 함수를 찾습니다. 이러한 함수가 내보내려는 함수입니다. 그런 다음 이러한 모든 함수 이름을 사용하여 __all__ 리스트를 추가합니다. 다음과 같이 표시됩니다.
__all__ = ['read_csv_as_instances', 'read_csv_as_dicts', 'read_csv_as_columns']
실제 함수 이름은 파일에서 찾은 내용에 따라 다를 수 있습니다. 찾은 모든 read_csv_as_* 함수를 포함해야 합니다. 파일을 저장하고 편집기를 종료합니다.
- 이제
tableformat.py를 수정해 보겠습니다.
touch ~/project/structly/tableformat.py
이 명령은 structly 디렉토리에 tableformat.py라는 새 파일을 만듭니다. 파일 맨 위에 이 줄을 추가합니다.
__all__ = ['create_formatter', 'print_table']
이 줄은 누군가 from tableformat import *를 사용할 때 create_formatter 및 print_table 심볼만 임포트하도록 지정합니다. 파일을 저장하고 편집기를 종료합니다.
__init__.py에서 통합 임포트
이제 각 모듈이 내보내는 내용을 정의했으므로 __init__.py 파일을 업데이트하여 이러한 모든 심볼을 임포트할 수 있습니다. __init__.py 파일은 Python 패키지에서 특별한 파일입니다. 패키지가 임포트될 때 실행되며, 패키지를 초기화하고 하위 모듈에서 심볼을 임포트하는 데 사용할 수 있습니다.
touch ~/project/structly/__init__.py
이 명령은 structly 디렉토리에 새 __init__.py 파일을 만듭니다. 파일의 내용을 다음과 같이 변경합니다.
## structly/__init__.py
from .structure import *
from .reader import *
from .tableformat import *
이러한 줄은 structure, reader 및 tableformat 하위 모듈에서 내보낸 모든 심볼을 임포트합니다. 모듈 이름 앞의 점 (.) 은 상대 임포트임을 나타냅니다. 즉, 동일한 패키지 내에서 임포트한다는 의미입니다. 파일을 저장하고 편집기를 종료합니다.
변경 사항 테스트
변경 사항이 제대로 작동하는지 확인하기 위해 간단한 테스트 파일을 만들어 보겠습니다. 이 테스트 파일은 __all__ 변수에 지정한 심볼을 임포트하려고 시도하고 임포트가 성공하면 성공 메시지를 출력합니다.
touch ~/project/test_structly.py
이 명령은 프로젝트 디렉토리에 test_structly.py라는 새 파일을 만듭니다. 파일에 이 내용을 추가합니다.
## A simple test to verify our imports work correctly
from structly import Structure
from structly import read_csv_as_instances
from structly import create_formatter, print_table
print("Successfully imported all required symbols!")
이러한 줄은 Structure 클래스, read_csv_as_instances 함수, create_formatter 및 print_table 함수를 structly 패키지에서 임포트하려고 시도합니다. 임포트가 성공하면 프로그램은 "Successfully imported all required symbols!" 메시지를 출력합니다. 파일을 저장하고 편집기를 종료합니다. 이제 이 테스트를 실행해 보겠습니다.
cd ~/project
python test_structly.py
cd ~/project 명령은 현재 작업 디렉토리를 프로젝트 디렉토리로 변경합니다. python test_structly.py 명령은 test_structly.py 스크립트를 실행합니다. 모든 것이 제대로 작동하면 화면에 "Successfully imported all required symbols!" 메시지가 표시됩니다.
패키지에서 모든 항목 내보내기
Python 에서 패키지 구성은 코드를 효과적으로 관리하는 데 매우 중요합니다. 이제 패키지 구성을 한 단계 더 발전시키겠습니다. 패키지 수준에서 어떤 심볼을 내보낼지 정의할 것입니다. 심볼을 내보낸다는 것은 특정 함수, 클래스 또는 변수를 코드의 다른 부분이나 패키지를 사용할 수 있는 다른 개발자가 사용할 수 있도록 하는 것을 의미합니다.
패키지에 __all__ 추가
Python 패키지로 작업할 때 누군가 from structly import * 문을 사용할 때 어떤 심볼에 액세스할 수 있는지 제어하고 싶을 수 있습니다. 이럴 때 __all__ 리스트가 유용합니다. 패키지의 __init__.py 파일에 __all__ 리스트를 추가하면 누군가 from structly import * 문을 사용할 때 정확히 어떤 심볼을 사용할 수 있는지 제어할 수 있습니다.
먼저, __init__.py 파일을 만들거나 업데이트해 보겠습니다. 파일이 없으면 touch 명령을 사용하여 파일을 만듭니다.
touch ~/project/structly/__init__.py
이제 __init__.py 파일을 열고 __all__ 리스트를 추가합니다. 이 리스트에는 내보내려는 모든 심볼이 포함되어야 합니다. 심볼은 structure, reader, tableformat 모듈과 같이 출처에 따라 그룹화됩니다.
## structly/__init__.py
from .structure import *
from .reader import *
from .tableformat import *
## Define what symbols are exported when using "from structly import *"
__all__ = ['Structure', ## from structure
'read_csv_as_instances', 'read_csv_as_dicts', 'read_csv_as_columns', ## from reader
'create_formatter', 'print_table'] ## from tableformat
코드를 추가한 후 파일을 저장하고 편집기를 종료합니다.
import * 이해
from module import * 패턴은 대부분의 Python 코드에서 일반적으로 권장되지 않습니다. 다음과 같은 몇 가지 이유가 있습니다.
- 예상치 못한 심볼로 네임스페이스를 오염시킬 수 있습니다. 즉, 현재 네임스페이스에 예상하지 못한 변수나 함수가 있을 수 있으며, 이는 이름 충돌로 이어질 수 있습니다.
- 특정 심볼의 출처를 알 수 없게 만듭니다.
import *를 사용하면 심볼이 어떤 모듈에서 오는지 알기 어려워 코드를 이해하고 유지 관리하기 어려울 수 있습니다. - 섀도잉 (shadowing) 문제가 발생할 수 있습니다. 섀도잉은 로컬 변수 또는 함수가 다른 모듈의 변수 또는 함수와 동일한 이름을 가질 때 발생하며, 이는 예상치 못한 동작을 유발할 수 있습니다.
그러나 import *를 사용하는 것이 적절한 특정 경우가 있습니다.
- 전체적으로 사용하도록 설계된 패키지의 경우. 패키지가 단일 단위로 사용되도록 되어 있는 경우
import *를 사용하면 필요한 모든 심볼에 더 쉽게 액세스할 수 있습니다. - 패키지가
__all__을 통해 명확한 인터페이스를 정의하는 경우.__all__리스트를 사용하면 내보낼 심볼을 제어하여import *를 더 안전하게 사용할 수 있습니다. - Python REPL(Read-Eval-Print Loop) 과 같은 대화형 사용의 경우. 대화형 환경에서는 모든 심볼을 한 번에 임포트하는 것이 편리할 수 있습니다.
Import *로 테스트
모든 심볼을 한 번에 임포트할 수 있는지 확인하기 위해 다른 테스트 파일을 만들어 보겠습니다. touch 명령을 사용하여 파일을 만듭니다.
touch ~/project/test_import_all.py
이제 test_import_all.py 파일을 열고 다음 내용을 추가합니다. 이 코드는 structly 패키지의 모든 심볼을 임포트한 다음 일부 중요한 심볼을 사용할 수 있는지 테스트합니다.
## Test importing everything at once
from structly import *
## Try using the imported symbols
print(f"Structure symbol is available: {Structure is not None}")
print(f"read_csv_as_instances symbol is available: {read_csv_as_instances is not None}")
print(f"create_formatter symbol is available: {create_formatter is not None}")
print(f"print_table symbol is available: {print_table is not None}")
print("All symbols successfully imported!")
파일을 저장하고 편집기를 종료합니다. 이제 테스트를 실행해 보겠습니다. 먼저 cd 명령을 사용하여 프로젝트 디렉토리로 이동한 다음 Python 스크립트를 실행합니다.
cd ~/project
python test_import_all.py
모든 것이 올바르게 설정되어 있으면 모든 심볼이 성공적으로 임포트되었음을 확인할 수 있습니다.
더 나은 코드 구성을 위한 모듈 분할
Python 프로젝트가 커짐에 따라 단일 모듈 파일이 상당히 커지고 여러 개의 관련되지만 별개의 구성 요소를 포함하게 될 수 있습니다. 이런 경우 모듈을 하위 모듈이 있는 패키지로 분할하는 것이 좋습니다. 이 접근 방식은 코드를 더 체계적으로 만들고, 유지 관리가 더 쉬워지며, 확장성이 향상됩니다.
현재 구조 이해
tableformat.py 모듈은 큰 모듈의 좋은 예입니다. 다음과 같이 데이터를 다른 방식으로 형식화하는 여러 형식 지정자 클래스를 포함합니다.
TableFormatter(base class): 다른 모든 형식 지정자 클래스의 기본 클래스입니다. 다른 클래스가 상속하고 구현할 기본 구조와 메서드를 정의합니다.TextTableFormatter: 일반 텍스트로 데이터를 형식화하는 클래스입니다.CSVTableFormatter: CSV(Comma-Separated Values) 형식으로 데이터를 형식화하는 클래스입니다.HTMLTableFormatter: HTML(Hypertext Markup Language) 형식으로 데이터를 형식화하는 클래스입니다.
이 모듈을 각 형식 지정자 유형에 대한 별도의 파일이 있는 패키지 구조로 재구성합니다. 이렇게 하면 코드가 더 모듈화되고 관리가 더 쉬워집니다.
1 단계: 캐시 파일 정리
코드를 재구성하기 전에 Python 캐시 파일을 정리하는 것이 좋습니다. 이러한 파일은 코드 실행 속도를 높이기 위해 Python 에서 생성되지만, 코드를 변경할 때 문제가 발생할 수 있습니다.
cd ~/project/structly
rm -rf __pycache__
위 명령에서 cd ~/project/structly는 현재 디렉토리를 프로젝트의 structly 디렉토리로 변경합니다. rm -rf __pycache__는 __pycache__ 디렉토리와 모든 내용을 삭제합니다. -r 옵션은 재귀적 (recursive) 을 의미하며, 이는 __pycache__ 디렉토리 내의 모든 파일과 하위 디렉토리를 삭제한다는 의미입니다. -f 옵션은 강제 (force) 를 의미하며, 확인 없이 파일을 삭제한다는 의미입니다.
2 단계: 새 패키지 구조 만들기
이제 패키지에 대한 새 디렉토리 구조를 만들어 보겠습니다. tableformat이라는 디렉토리와 그 안에 formats라는 하위 디렉토리를 만듭니다.
mkdir -p tableformat/formats
mkdir 명령은 디렉토리를 만드는 데 사용됩니다. -p 옵션은 부모 (parents) 를 의미하며, 필요한 상위 디렉토리가 없으면 모두 생성한다는 의미입니다. 따라서 tableformat 디렉토리가 없으면 먼저 생성된 다음 그 안에 formats 디렉토리가 생성됩니다.
3 단계: 원본 파일 이동 및 이름 바꾸기
다음으로, 원본 tableformat.py 파일을 새 구조로 이동하고 이름을 formatter.py로 바꿉니다.
mv tableformat.py tableformat/formatter.py
mv 명령은 파일을 이동하거나 이름을 바꾸는 데 사용됩니다. 이 경우 tableformat.py 파일을 tableformat 디렉토리로 이동하고 이름을 formatter.py로 바꿉니다.
4 단계: 코드를 별도 파일로 분할
이제 각 형식 지정자에 대한 파일을 만들고 관련 코드를 해당 파일로 이동해야 합니다.
1. 기본 형식 지정자 파일 만들기
touch tableformat/formatter.py
touch 명령은 빈 파일을 만드는 데 사용됩니다. 이 경우 tableformat 디렉토리에 formatter.py라는 파일을 만듭니다.
TableFormatter 기본 클래스와 print_table 및 create_formatter와 같은 일반 유틸리티 함수는 이 파일에 유지합니다. 파일은 다음과 같이 표시됩니다.
## Base TableFormatter class and utility functions
__all__ = ['TableFormatter', 'print_table', 'create_formatter']
class TableFormatter:
def headings(self, headers):
'''
Emit table headings.
'''
raise NotImplementedError()
def row(self, rowdata):
'''
Emit a single row of table data.
'''
raise NotImplementedError()
def print_table(objects, columns, formatter):
'''
Make a nicely formatted table from a list of objects and attribute names.
'''
formatter.headings(columns)
for obj in objects:
rowdata = [getattr(obj, name) for name in columns]
formatter.row(rowdata)
def create_formatter(fmt):
'''
Create an appropriate formatter given an output format name.
'''
if fmt == 'text':
from .formats.text import TextTableFormatter
return TextTableFormatter()
elif fmt == 'csv':
from .formats.csv import CSVTableFormatter
return CSVTableFormatter()
elif fmt == 'html':
from .formats.html import HTMLTableFormatter
return HTMLTableFormatter()
else:
raise ValueError(f'Unknown format {fmt}')
__all__ 변수는 from module import *를 사용할 때 어떤 심볼을 임포트해야 하는지 지정하는 데 사용됩니다. 이 경우 TableFormatter, print_table 및 create_formatter 심볼만 임포트하도록 지정합니다.
TableFormatter 클래스는 다른 모든 형식 지정자 클래스의 기본 클래스입니다. headings 및 row의 두 가지 메서드를 정의하며, 이는 서브클래스에서 구현하도록 되어 있습니다.
print_table 함수는 객체 목록, 열 이름 목록 및 형식 지정자 객체를 가져와 데이터를 형식화된 테이블로 출력하는 유틸리티 함수입니다.
create_formatter 함수는 형식 이름을 인수로 받아 적절한 형식 지정자 객체를 반환하는 팩토리 함수입니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
2. 텍스트 형식 지정자 만들기
touch tableformat/formats/text.py
이 파일에 TextTableFormatter 클래스만 추가합니다.
## Text formatter implementation
__all__ = ['TextTableFormatter']
from ..formatter import TableFormatter
class TextTableFormatter(TableFormatter):
'''
Emit a table in plain-text format
'''
def headings(self, headers):
print(' '.join('%10s' % h for h in headers))
print(('-'*10 + ' ')*len(headers))
def row(self, rowdata):
print(' '.join('%10s' % d for d in rowdata))
__all__ 변수는 from module import *를 사용할 때 TextTableFormatter 심볼만 임포트하도록 지정합니다.
from ..formatter import TableFormatter 문은 상위 디렉토리의 formatter.py 파일에서 TableFormatter 클래스를 임포트합니다.
TextTableFormatter 클래스는 TableFormatter 클래스를 상속하고 headings 및 row 메서드를 구현하여 데이터를 일반 텍스트로 형식화합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
3. CSV 형식 지정자 만들기
touch tableformat/formats/csv.py
이 파일에 CSVTableFormatter 클래스만 추가합니다.
## CSV formatter implementation
__all__ = ['CSVTableFormatter']
from ..formatter import TableFormatter
class CSVTableFormatter(TableFormatter):
'''
Output data in CSV format.
'''
def headings(self, headers):
print(','.join(headers))
def row(self, rowdata):
print(','.join(str(d) for d in rowdata))
이전 단계와 유사하게 __all__ 변수를 지정하고, TableFormatter 클래스를 임포트하고, headings 및 row 메서드를 구현하여 데이터를 CSV 형식으로 형식화합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
4. HTML 형식 지정자 만들기
touch tableformat/formats/html.py
이 파일에 HTMLTableFormatter 클래스만 추가합니다.
## HTML formatter implementation
__all__ = ['HTMLTableFormatter']
from ..formatter import TableFormatter
class HTMLTableFormatter(TableFormatter):
'''
Output data in HTML format.
'''
def headings(self, headers):
print('<tr>', end='')
for h in headers:
print(f'<th>{h}</th>', end='')
print('</tr>')
def row(self, rowdata):
print('<tr>', end='')
for d in rowdata:
print(f'<td>{d}</td>', end='')
print('</tr>')
다시, __all__ 변수를 지정하고, TableFormatter 클래스를 임포트하고, headings 및 row 메서드를 구현하여 데이터를 HTML 형식으로 형식화합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
5 단계: 패키지 초기화 파일 만들기
Python 에서 __init__.py 파일은 디렉토리를 Python 패키지로 표시하는 데 사용됩니다. tableformat 및 formats 디렉토리 모두에 __init__.py 파일을 만들어야 합니다.
1. tableformat 패키지에 대한 파일 만들기
touch tableformat/__init__.py
파일에 이 내용을 추가합니다.
## Re-export the original symbols from tableformat.py
from .formatter import *
이 문은 formatter.py 파일의 모든 심볼을 임포트하고 tableformat 패키지를 임포트할 때 사용할 수 있도록 합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
2. formats 패키지에 대한 파일 만들기
touch tableformat/formats/__init__.py
이 파일은 비워두거나 간단한 docstring 을 추가할 수 있습니다.
'''
Format implementations for different output formats.
'''
docstring 은 formats 패키지가 수행하는 작업에 대한 간략한 설명을 제공합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다.
6 단계: 새 구조 테스트
변경 사항이 제대로 작동하는지 확인하기 위해 간단한 테스트를 만들어 보겠습니다.
cd ~/project
touch test_tableformat.py
test_tableformat.py 파일에 이 내용을 추가합니다.
## Test the tableformat package restructuring
from structly import *
## Create formatters of each type
text_fmt = create_formatter('text')
csv_fmt = create_formatter('csv')
html_fmt = create_formatter('html')
## Define some test data
class TestData:
def __init__(self, name, value):
self.name = name
self.value = value
## Create a list of test objects
data = [
TestData('apple', 10),
TestData('banana', 20),
TestData('cherry', 30)
]
## Test text formatter
print("\nText Format:")
print_table(data, ['name', 'value'], text_fmt)
## Test CSV formatter
print("\nCSV Format:")
print_table(data, ['name', 'value'], csv_fmt)
## Test HTML formatter
print("\nHTML Format:")
print_table(data, ['name', 'value'], html_fmt)
이 테스트 코드는 structly 패키지에서 필요한 함수와 클래스를 임포트하고, 각 유형의 형식 지정자를 만들고, 일부 테스트 데이터를 정의한 다음, 해당 형식으로 데이터를 출력하여 각 형식 지정자를 테스트합니다.
이러한 변경을 한 후 파일을 저장하고 종료합니다. 이제 테스트를 실행합니다.
python test_tableformat.py
세 가지 다른 방식 (텍스트, CSV 및 HTML) 으로 형식화된 동일한 데이터가 표시되어야 합니다. 예상 출력이 표시되면 코드 재구성이 성공한 것입니다.
요약
이 랩에서는 몇 가지 중요한 Python 패키지 구성 기술을 배웠습니다. 먼저, 모듈에서 내보내는 심볼을 명시적으로 정의하기 위해 __all__ 변수를 사용하는 방법을 익혔습니다. 둘째, 최상위 패키지에서 하위 모듈 심볼을 다시 내보내어 사용자 친화적인 패키지 인터페이스를 만들었습니다.
이러한 기술은 깨끗하고, 유지 관리 가능하며, 사용자 친화적인 Python 패키지를 만드는 데 필수적입니다. 이를 통해 사용자의 보기를 제어하고, 임포트 프로세스를 단순화하며, 프로젝트가 확장됨에 따라 코드를 논리적으로 구성할 수 있습니다.