Python의 구문은 간단하고 자연어에 가깝습니다. 초보 프로그래머라도 학습 임계값을 낮추어 빠르게 시작할 수 있습니다.
Python은 네트워킹, 데이터 처리 및 그래픽 인터페이스와 같은 다양한 측면을 다루는 광범위한 표준 함수 라이브러리를 제공합니다. 또한 NumPy, Pandas, TensorFlow와 같은 강력한 타사 생태계는 Python을 다목적 개발 도구로 만듭니다.
Python은 크로스 플랫폼 언어입니다. Windows, macOS, Linux 등 동일한 Python 프로그램을 실행할 수 있어 개발 유연성이 크게 향상됩니다.
Python은 데이터 과학, 인공 지능, 웹 개발, 자동화 스크립팅, 게임 개발 등 여러 분야에서 중요한 역할을 수행하므로 개발자는 하나의 언어로 여러 요구 사항을 처리할 수 있습니다.
Python은 대규모 글로벌 커뮤니티를 보유하고 있으며 초보자와 숙련된 개발자 모두 교육 리소스, 토론 그룹 및 기술 지원을 쉽게 찾을 수 있습니다.
Python은 직관적인 구문과 강력한 도구를 제공하므로 개발자는 프로그래밍을 더 빠르게 구현하고 제품 개발 주기를 단축할 수 있습니다.
Anaconda는 데이터 과학, 기계 학습, 인공 지능, 빅 데이터 분석과 같은 애플리케이션을 포함한 과학 컴퓨팅을 위해 설계된 오픈 소스 Python 및 R 프로그래밍 플랫폼입니다.
Anaconda는 다음 분야의 사용자에게 적합합니다:
다음은 사용자가 흔히 겪는 문제입니다.
터미널에 입력 가능conda update conda그리고conda update anaconda。
Anaconda는 프로그래밍 언어인 Python을 다양한 내장 도구 및 라이브러리와 통합하는 데이터 과학 플랫폼입니다.
Anaconda는 사용자가 동일한 컴퓨터에서 여러 개의 독립적인 Python 실행 환경을 만들 수 있도록 하는 가상 환경(Environment) 기능을 제공합니다. 각 환경에는 서로 다른 프로젝트 간의 종속성 충돌을 피하기 위해 서로 다른 Python 버전과 패키지가 있을 수 있습니다.
# myenv라는 환경을 생성하고 Python 버전을 지정합니다.
conda create -n myenv python=3.10
# 시작 환경
conda는 myenv를 활성화합니다
#환경에서 나가기
콘다 비활성화
# 모든 환경 나열
콘다 환경 목록
# 또는
콘다 정보 --envs
# 환경 구성을 YAML 파일로 내보내기
conda env 내보내기 > Environment.yml
# YAML 파일에서 환경 생성
conda env create -f 환경.yml
# 지정된 환경을 삭제합니다
conda 제거 -n myenv --all
Jupyter는 다양한 프로그래밍 언어를 지원하는 오픈소스 대화형 컴퓨팅 환경으로 주로 데이터 과학, 머신러닝, 학술 연구에 사용됩니다.
Jupyter는 다음 분야에서 널리 사용됩니다.
jupyter notebook주피터 노트북을 시작합니다.이동비주얼 스튜디오 코드 공식 홈페이지, 운영 체제에 적합한 버전을 다운로드하여 설치하십시오.
Visual Studio Code에서 다음 단계에 따라 Python 확장을 설치합니다.
Python이 시스템에 설치되어 있는지 확인하십시오. 에서 얻을 수 있습니다파이썬 공식 홈페이지다운로드하여 설치하세요.
설치가 완료되면 명령줄에 다음 명령을 입력하여 설치가 성공했는지 확인합니다.
파이썬 --버전
# 또는
python3 --버전
Python 프로젝트 또는 파일을 열고 Visual Studio Code의 오른쪽 아래 모서리에 있는 "Python" 상태 표시줄을 클릭하고 적절한 Python 인터프리터를 선택합니다.
편집기에서 Python 파일을 열고 다음 방법을 사용하여 프로그램을 실행합니다.
Ctrl + Shift + P, "Python 파일 실행"을 검색하여 실행하세요.타사 패키지를 설치해야 하는 경우 내장 터미널을 사용하여 다음을 입력할 수 있습니다.
pip 설치 패키지 이름
Python 확장이 제공하는 기능을 통해 자동 완성 및 강력한 디버깅 도구를 사용해 보세요.
일반적으로 사용되는 단축키는 다음과 같습니다.
Ctrl + F5Ctrl + Shift + PShift + Alt + FCtrl + `Python 프로그램을 실행할 때 매개변수를 전달해야 하는 경우 다음을 설정할 수 있습니다.launch.json마치다:
launch.json파일에서 관련 설정을 수정합니다.다음은 프로그램 경로 및 실행 매개변수를 포함한 예시 구성입니다.
{
"버전": "0.2.0",
"구성": [
{
"name": "Python: 인수를 사용하여 실행",
"유형": "파이썬",
"요청": "실행",
"program": "${workspaceFolder}/main.py", // 프로그램 경로
"console": "integratedTerminal", // 터미널 유형
"args": ["arg1", "arg2", "--option", "value"] // 매개변수 전달
}
]
}
존재하다args명령줄 매개변수는 다음과 같이 전달될 수 있습니다.
arg1그리고arg2위치 매개변수입니다.--option그리고value옵션이 포함된 매개변수입니다.사용sys.argv명령줄에서 전달된 매개변수를 읽으려면 다음 안내를 따르세요.
importsys
print("모든 매개변수:", sys.argv)
len(sys.argv) > 1인 경우:
print("첫번째 매개변수:", sys.argv[1])
print("두 번째 매개변수:", sys.argv[2])
프로그램이 다음과 같다고 가정합니다:
python main.py arg1 arg2 --option value
실행 결과:
모든 매개변수: ['main.py', 'arg1', 'arg2', '--option', 'value']
첫 번째 매개변수: arg1
두 번째 매개변수: arg2
1. 설치Python Extension확대.
2. VS Code에서 Python 프로젝트를 시작합니다.
3. 누르기F5또는 왼쪽의 활동 표시줄을 클릭하세요.Debug상.
1. 디버그 패널에서 "구성 추가"를 클릭합니다.
2. 선택Python, 시스템이 자동으로launch.json。
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
1. 중단점을 추가하려면 코드 줄 번호 옆을 클릭하세요.
2. 조건부 중단점을 사용할 수 있습니다. 중단점을 마우스 오른쪽 버튼으로 클릭하고 "조건 편집"을 선택합니다.
F10건너뛰기 기능.F11함수 내부로 들어갑니다.Shift+F11기능에서 뛰어내립니다.1. 디버그 패널의 '변수' 영역에서 현재 변수 상태를 확인하세요.
2. "모니터" 영역에서 특정 표현식을 수동으로 추가할 수 있습니다.
1. 디버그 콘솔에 Python 명령을 입력하여 프로그램 상태를 실시간으로 확인합니다.
2. 변수 쿼리, 함수 호출 등의 작업을 수행할 수 있습니다.
Python이 설치되어 시스템 환경 변수에 추가되었는지 확인한 다음 Visual Studio Code를 다운로드하여 설치합니다.
Visual Studio Code를 열고 왼쪽의 확장 아이콘을 클릭한 후 검색하세요.Python를 클릭한 다음 Microsoft에서 제공하는 Python 확장을 설치합니다.
Python의 설치 경로를 확인하려면 터미널에 다음 명령을 입력하십시오.
which python
또는 (Windows 시스템):
where python
Visual Studio Code에서 다음을 누릅니다.Ctrl + Shift + P, 입력 및 선택Python: Select Interpreter。
매니페스트에서 올바른 Python 경로를 선택합니다. 표시되지 않으면 전체 경로를 수동으로 입력하세요.
터미널을 열고 실행python --version올바른 버전의 Python 인터프리터가 선택되었는지 확인합니다.
특정 프로젝트의 Python 경로가 필요한 경우 프로젝트 루트 디렉터리에 추가할 수 있습니다..vscode/settings.json파일을 만들고 다음 내용을 추가합니다.
{
"python.pythonPath": "Python의 전체 경로"
}
바꾸다Python 전체 경로실제 경로입니다.
VS Code로 개발할 때 주로 기본 인터프리터(Interpreter) 설정을 통해 Anaconda나 다른 환경을 사용하기로 결정합니다. 이렇게 하면 패키지 종속성이 프로그램 실행 환경에서 완전히 격리됩니다.
| 환경 유형 | 적용 가능한 상황 | 주요 장점 |
|---|---|---|
| Anaconda | 데이터 과학, 머신러닝, 딥러닝 | 다수의 과학 컴퓨팅 라이브러리가 사전 설치되어 있으며 기본 바이너리 파일(예: DLL)을 강력하게 관리합니다. |
| Venv | 일반 웹 개발, 자동화 스크립트 | 가볍고 시작이 빠르며 실행에 필요한 패키지만 포함되어 있습니다. |
그래픽 인터페이스 외에도 VS Code의 내장 터미널에 있는 명령을 사용하여 환경을 관리할 수도 있습니다.
conda env listconda 활성화 환경 이름conda create -n 이름 python=3.10Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser。
sudo apt update
sudo apt install python3 python3-pip -y
python3Python 대화형 환경으로 들어갑니다.pip3 설치 모듈 이름。
sudo apt install wget gpg -y
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] \
https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt update
sudo apt install code -y
pip --version
pip 설치 패키지 이름
예를 들어:pip install requests
pip install --업그레이드 패키지 이름
예를 들어:pip install --upgrade requests
pip list
pip 제거 패키지 이름
예를 들어:pip uninstall requests
pip list --outdated
pip 설치 패키지 이름==버전 번호
예를 들어:pip install requests==2.26.0
pip install -r requirements.txt
사용requirements.txt필요한 모든 패키지 이름과 버전을 나열하는 파일입니다.
pip freeze > requirements.txt
이 명령은 현재 환경의 패키지와 버전을 요구 사항 아카이브로 내보냅니다.
pip cache purge
pip의 캐시 폴더를 정리하여 디스크 공간을 확보하세요.
해결 방법: Python이 설치되었는지 확인하고 Python 설치 디렉터리가 시스템의 PATH 환경 변수에 추가되었는지 확인하세요.
해결 방법: 추가해 보세요.--user매개변수는 다음과 같습니다.pip 설치 패키지 이름 --user
해결책: 네트워크가 정상인지 확인하거나 국내 미러 소스를 사용해 보십시오. 예를 들면 다음과 같습니다.pip 설치 패키지 이름 -i https://pypi.tuna.tsinghua.edu.cn/simple
venv또는virtualenv) 전역 설치 패키지와의 충돌을 방지합니다.requirements.txt종속성을 관리합니다.http-v2나중에 동일한 패키지를 설치할 때 다시 다운로드할 필요가 없도록 디렉터리에 저장합니다.pip cache dir현재 캐시 디렉터리를 봅니다.pip cache purge캐시된 데이터를 모두 지웁니다.http-v2폴더에 저장되지만, 이로 인해 다음에 관련 패키지를 설치할 때 pip가 파일을 다시 다운로드하게 됩니다.--no-cache-dir매개변수 예:pip install package_name --no-cache-dir。
type()이 함수는 객체의 유형을 반환할 수 있습니다.
x = 10
print(type(x)) # <class 'int'>
y = "hello"
print(type(y)) # <class 'str'>
isinstance()변수가 특정 유형에 속하는지 확인하고 다중 유형 검사를 지원하는 데 사용됩니다.
x = 10
print(isinstance(x, int)) # True
print(isinstance(x, str)) # False
print(isinstance(x, (int, float))) # True
type()비교적 엄격하므로 정확한 유형만 반환됩니다.isinstance()상속 관계가 고려될 것이며 실제로는 더 일반적으로 사용됩니다.Python의 부울은 True 또는 False라는 두 가지 논리적 상태를 나타내는 프로그래밍의 기본 데이터 유형입니다. 이는 모든 조건부 판단과 프로세스 제어의 기초가 됩니다.
True그리고False。bool。a = 사실
b = 거짓
print(type(a)) # 출력: <class 'bool'>
파이썬 내부,bool정수이다int의 하위 범주이므로 숫자 연산에 참여할 수 있습니다.
True수치적으로는 1과 동일합니다.False수치적으로는 0과 동일합니다.print(True + 1) # 출력: 2 (1 + 1)
print(False * 5) # 출력: 0 (0 * 5)
비교 연산자는 두 값을 비교하고 부울 결과를 반환합니다.
| 연산자 | 설명하다 | 예 | 결과 |
|---|---|---|---|
== |
동일한 | 10 == 10 |
True |
!= |
같지 않음 | 5 != 10 |
True |
> |
보다 큼 | 10 > 5 |
True |
<= |
보다 작거나 같음 | 5 <= 5 |
True |
논리 연산자는 부울 값 또는 부울 표현식을 결합하거나 수정하는 데 사용됩니다.
and: 논리적 "and", 양쪽 모두True결과는True。or: 논리적 "OR", 어느 쪽이든 가능True결과는True。not: 논리적 "not", 부울 값을 반전합니다.print(True 및 False) # 출력: False
print(True 또는 False) # 출력: True
print(not True) # 출력: False
Python에서는 모든 객체에 진리값이 있습니다. 조건부 판단에 객체가 사용되면 Python은 이를 다음으로 변환합니다.True또는False:
False(거짓) 개체에는 다음이 포함됩니다.None, 숫자 0 (0, 0.0), 빈 문자열(""), 빈 목록([]), 빈 튜플(()), 빈 사전({}) 및 빈 세트(set())。True(진실한) 객체에는 거짓 값을 제외한 기타 모든 객체가 포함됩니다(예: 0이 아닌 숫자, 비어 있지 않은 컨테이너).if []: # 빈 목록은 False로 처리됩니다.
print("실행되지 않습니다.")
그 외:
print("목록이 비어있습니다.")
if "hello": # 비어 있지 않은 문자열은 True로 간주됩니다.
print("문자열이 비어있지 않습니다.")
Python에서 배열은 동일한 유형의 여러 요소를 저장하는 데 사용되는 데이터 구조입니다. Python 자체에는 배열 유형이 내장되어 있지 않지만 다음을 사용할 수 있습니다.list또는array유사한 기능을 구현하는 모듈입니다.
list다양한 유형의 데이터를 저장할 수 있지만 배열을 시뮬레이션하는 데에도 사용할 수 있는 Python의 내장 데이터 구조입니다.
my_list = [1, 2, 3, 4, 5]
print(my_list[0]) # 출력: 1
실제 배열이 필요한 경우(모든 요소는 동일한 유형이어야 함) 다음을 사용할 수 있습니다.array개조.
배열 가져오기
my_array = array.array('i', [1, 2, 3, 4, 5])
print(my_array[0]) # 출력: 1
여기,'i'배열의 요소가 정수임을 나타냅니다.
다음은 몇 가지 기본 작업입니다.
my_array.append(6)my_array.remove(3)len(my_array)수치연산이 필요한 상황에서는numpy더욱 강력한 어레이 지원을 제공합니다.
numpy를 np로 가져오기
my_numpy_array = np.array([1, 2, 3, 4, 5])
print(my_numpy_array[0]) # 출력: 1
NumPy 배열은 다차원 데이터와 벡터화된 작업을 지원하므로 대량의 데이터를 처리하는 데 이상적입니다.
Python은 배열 함수를 구현하는 다양한 방법을 제공합니다.list일반적인 상황에 적용 가능array모듈은 동일한 유형의 요소가 필요한 상황에 적합하지만numpy과학 컴퓨팅을 위해 선택한 도구입니다.
변수에 대한ret_value = [], Python 언어에서 빈 목록인지 확인하는 몇 가지 간단하고 효율적인 방법이 있습니다. 빈 목록은 다음과 같이 처리되므로False, 다음은 일반적으로 사용되는 몇 가지 판단 방법입니다.
이는 목록의 부울 값을 직접 확인하는 가장 널리 사용되는 방법입니다. 목록이 비어 있는 경우not연산자는 조건을 true로 평가합니다(True)。
ret_value = []
ret_value가 아닌 경우:
#목록이 비어 있으면 여기서 실행
print("ret_value는 빈 목록입니다.")
그 외:
#목록이 비어 있지 않으면 여기서 실행
print("ret_value는 빈 목록이 아닙니다.")
len()기능목록의 길이가 0인지 확인합니다.
ret_value = []
len(ret_value) == 0인 경우:
print("ret_value는 빈 목록입니다.")
그 외:
print("ret_value는 빈 목록이 아닙니다.")
== []빈 목록 리터럴에 변수를 직접 할당[]비교해보세요.
ret_value = []
ret_value == []인 경우:
print("ret_value는 빈 목록입니다.")
그 외:
print("ret_value는 빈 목록이 아닙니다.")
파이썬에서는list요소를 쉽게 추가하고 제거할 수 있는 동적 데이터 구조입니다.
다음 방법을 사용하여 새 요소를 추가할 수 있습니다.
append(): 목록의 끝에 요소를 추가합니다.insert(): 지정된 인덱스 위치에 요소를 삽입합니다.extend(): 다른 목록의 요소를 기존 목록에 추가합니다.# 새 요소의 예
my_list = [1, 2, 3]
my_list.append(4) # [1, 2, 3, 4]
my_list.insert(1, 10) # [1, 10, 2, 3, 4]
my_list.extend([5, 6]) # [1, 10, 2, 3, 4, 5, 6]
다음을 사용하여 요소를 제거할 수 있습니다.
pop(): 인덱스를 기준으로 요소를 제거합니다. 기본값은 마지막 요소를 제거합니다.remove(): 값을 기준으로 첫 번째로 일치하는 요소를 제거합니다.clear(): 목록에서 모든 요소를 제거합니다.# 요소 제거 예시
my_list = [1, 2, 3, 4, 5]
my_list.pop() # [1, 2, 3, 4]
my_list.remove(2) # [1, 3, 4]
my_list.clear() # []
동일한 유형의 요소가 필요한 경우 다음을 사용할 수 있습니다.array개조.
append()그리고extend()방법이 적용됩니다array개조.
import array
my_array = array.array('i', [1, 2, 3])
my_array.append(4) # [1, 2, 3, 4]
my_array.extend([5, 6]) # [1, 2, 3, 4, 5, 6]
remove()그리고pop()방법을 사용할 수 있습니다array개조.
# 요소 제거 예시
my_array = array.array('i', [1, 2, 3, 4])
my_array.remove(2) # [1, 3, 4]
my_array.pop() # [1, 3]
Python은 배열을 동적으로 늘리거나 줄이는 다양한 방법을 제공합니다.list그리고array모듈은 다양한 요구에 적합합니다. 더 많은 기능적 요구 사항이 있는 경우 다음을 사용할 수도 있습니다.numpy。
파이썬에서는list.count()통계를 위해 특별히 사용되는 도구입니다.특정 요소의 발생 횟수방법. 목록의 길이를 구하는 것과 같습니다.len()이와는 달리 매개변수를 비교 개체로 전달해야 합니다.
구문은 다음과 같습니다list.count(value), 값이 목록에 나타나는 정수 횟수를 반환합니다. 값이 없으면 0이 반환됩니다.
과일 = ['사과', '바나나', '사과', '오렌지', '사과']
# '사과'가 나타나는 횟수를 센다
apple_count = Fruits.count('사과')
print(apple_count) # 출력: 3
# 존재하지 않는 요소의 개수를 센다
포도_수 = 과일.수('포도')
print(grape_count) # 출력: 0
요구 사항(단일 요소, 여러 요소 또는 모든 통계를 찾고 있는지 여부)에 따라 다양한 모범 사례가 있습니다.
| 필요 | 권장 방법 | 샘플 코드 |
|---|---|---|
| 단일 특정 요소 계산 | list.count() |
arr.count(10) |
| 목록의 전체 길이를 가져옵니다. | len() |
len(arr) |
| 모든 요소의 빈도를 계산합니다. | collections.Counter |
Counter(arr) |
| 조건 수(5보다 큰 경우) | 생성기 표현 | sum(1 for x in arr if x > 5) |
"모든 요소"가 목록에 동시에 몇 번 나타나는지 알고 싶다면 다음을 사용하세요.Counter여러 번 실행됩니다count()훨씬 더 효율적입니다(O(n) 대 O(n^2)).
컬렉션 수입 카운터에서
데이터 = [1, 2, 2, 3, 3, 3, 4]
개수 = 카운터(데이터)
print(counts) # 출력: Counter({3: 3, 2: 2, 1: 1, 4: 1})
print(counts[3]) # 3번의 횟수를 구합니다: 3
print(counts.most_common(1)) # 가장 많이 나타나는 요소를 가져옵니다.
if x in list비교하다if list.count(x) > 0훨씬 빠르니까요.in첫 번째 항목을 찾으면 즉시 중지됩니다.count()"얕은 비교"만 수행됩니다. 목록에 다른 목록이 포함되어 있으면 하위 목록 내에서 계산되지 않습니다.list.count()성능이 급격히 저하되므로 우선순위를 두어야 합니다.Counter。특정 논리(예: 길이가 3보다 큰 문자열)를 준수하는 요소의 수를 계산하려면 다음을 결합하면 됩니다.sum():
단어 = ['안녕하세요', '안녕하세요', '파이썬', 'a', '코드']
# 길이가 3보다 큰 단어 수를 셉니다.
big_word_count = sum(len(w) > 3인 경우 단어의 w에 대해 1)
print(big_word_count) # 출력: 3
[key, value]。목록1 = [
["a", 1],
["b", 2],
["c", 3]
]
목록2 = [
["c", 30],
["a", 10],
["d", 40]
]
#list1을 dict로 변환
dict1 = {k: v for k, v in list1}
dict2 = {k: v for k, v in list2}
# 모든 키 찾기
all_keys = sorted(set(dict1.keys()) | set(dict2.keys()))
# 결과 병합
병합 = []
all_keys의 k에 대해:
v1 = dict1.get(k)
v2 = dict2.get(k)
merged.append([k, v1, v2])
병합된 행의 경우:
인쇄(행)
['a', 1, 10]
['b', 2, None]
['c', 3, 30]
['d', None, 40]
None채우다.[key, value1, value2]。Python에서 두 개의 목록이 있는 경우(예:selected_fields_list그리고aSqlValuesStr_list) 동시에 반복해야 하며, 가장 일반적이고 Pythonic한 방법은 내장된zip()기능.
zip()이 함수는 여러 반복 가능한 객체(Iterable)를 일련의 튜플로 압축합니다. 루프를 반복할 때마다 각 목록의 해당 위치에 있는 요소가 제거됩니다.
다시 가져오기
# 이것이 re.split() 후에 얻는 두 개의 목록이라고 가정합니다.
selected_fields = "이름, 나이, 도시"
aSqlValuesStr = "앨리스, 25, 타이페이"
selected_fields_list = re.split(r',', selected_fields)
aSqlValuesStr_list = re.split(r',', aSqlValuesStr)
# for 루프를 실행
필드의 경우 zip(selected_fields_list, aSqlValuesStr_list)의 값:
print(f"필드: {필드}, 값: {값}")
필드: 이름, 값: Alice
필드: 연령, 값: 25
필드: 도시, 값: 타이페이
당신이 사용할 때zip()기능을 사용할 때 다음 사항에 주의해야 합니다.
zip()가장 짧은 목록으로 반복이 중지됩니다. 만약에selected_fields_list3가지 요소를 갖고 있으며,aSqlValuesStr_list요소가 4개인 경우 루프는 3번만 실행됩니다.itertools.zip_longest。#예: 목록 길이가 일관되지 않습니다.
목록1 = [1, 2, 3]
list2 = ['a', 'b']
zip(list1, list2)의 item1, item2에 대해:
인쇄(항목1, 항목2)
#출력은 다음과 같습니다:
# 1a
#2b
데이터 = [
[1, 23, 456],
[7890, 12, 3],
[45, 678, 9]
]
# 각 열의 최대 너비를 계산합니다.
col_widths = [max(len(str(row[i])) for row in data) for i in range(len(data[0]))]
# 형식 출력
데이터 행의 경우:
print(" ".join(str(val).rjust(col_widths[i]) for i, val in enumerate(row)))
1 23 456
7890 12 3
45 678 9
타사 패키지tabulate정렬된 테이블을 직접 출력할 수 있습니다.
from tabulate import tabulate
data = [
[1, 23, 456],
[7890, 12, 3],
[45, 678, 9]
]
print(tabulate(data, tablefmt="grid"))
+------+-----+-----+
| 1 | 23 | 456 |
| 7890 | 12 | 3 |
| 45 | 678 | 9 |
+------+-----+-----+
rjust()조정.tabulate아름다운 테이블을 빠르게 생성하세요.다음 예에서는 2차원 목록을 인쇄하는 방법을 보여줍니다. 요소가float소수점 이하 두 자리 표시가 수정되었으며, 다른 요소는 필드 정렬을 유지하면서 그대로 출력됩니다.
데이터 = [
[1, 23.456, 456],
[7890.1, 12, 3.5],
[45, 678.9, 9]
]
# 각 요소 문자열의 형식을 지정합니다.
formatted_data = []
데이터 행의 경우:
new_row = []
행의 값:
isinstance(val, float)인 경우:
s = f"{val:.2f}" # float -> 소수점 이하 두 자리
그 외:
s = str(발)
new_row.append(들)
formatted_data.append(new_row)
# 각 열의 최대 너비를 계산합니다.
col_widths = [formatted_data의 행에 대한 max(len(row[i])) for i in range(len(formatted_data[0]))]
# 형식 출력
formatted_data의 행에 대해:
print(" ".join(val.rjust(col_widths[i]) for i, val in enumerate(row)))
1 23.46 456
7890.10 12 3.50
45 678.90 9
isinstance(val, float)부동 소수점 숫자를 결정합니다.f"{val:.2f}"부동 소수점 숫자를 소수점 이하 두 자리로 형식화합니다.제공하는 데이터 구조는 여러 사전을 포함하는 목록입니다. 여기서 각 사전은 시계열 레코드(예: K-라인 데이터)를 나타냅니다.
data = [
{'time': 1759028400000, 'open': '109398.3', 'close': '109364.8', 'high': '109489.2', 'low': '109364.8', 'volume': '518.7594'},
{'time': 1759024800000, 'open': '109305.6', 'close': '109398.3', 'high': '109496.4', 'low': '109296.0', 'volume': '757.0290'},
# ...
]
모든 레코드의 모든 값을 얻으려면 (1759028400000, '109398.3', '109364.8'등)을 목록으로 수집하면 Nested List Comprehension을 사용할 수 있습니다.
2단계 목록 이해를 사용하여 목록의 각 사전을 반복한 다음 호출합니다..values()메소드는 값을 가져오고 최종적으로 모든 값을 단순 목록으로 수집합니다.
데이터 = [
{'시간': 1759028400000, '개시': '109398.3', '종료': '109364.8', '높음': '109489.2', '낮음': '109364.8', '볼륨': '518.7594'},
{'시간': 1759024800000, '개시': '109305.6', '종료': '109398.3', '높음': '109496.4', '낮음': '109296.0', '볼륨': '757.0290'}
]
모든 값 = [
가치
for Record in data # 외부 목록의 각 사전 레코드를 탐색합니다.
for value in Record.values() # 사전 레코드의 모든 값을 탐색합니다.
]
인쇄(모든_값)
그러면 모든 값을 포함하는 단일 목록이 생성됩니다.
[1759028400000, '109398.3', '109364.8', '109489.2', '109364.8', '518.7594', 1759024800000, '109305.6', '109398.3', '109496.4', '109296.0', '757.0290']
특정 필드만 추출해야 하는 경우(예: 모든 필드open가격), 단일 수준 목록 이해를 사용할 수 있습니다.
data = [
{'time': 1759028400000, 'open': '109398.3', ...},
{'time': 1759024800000, 'open': '109305.6', ...}
]
open_prices = [record['open'] for record in data]
print(open_prices)
출력 결과:
['109398.3', '109305.6']
List comprehension은 기존 목록에서 새 목록을 생성하기 위한 간결한 한 줄 구문입니다.
날짜/시간에서 날짜/시간 가져오기
데이터_목록 = [
{'videoid': 'b5HxsaM_E2Y', 'publishedat': datetime(2025, 12, 7, 3, 0, 53), 'rankno': 7, 'viewcount': 913053, 'query': '야구'},
{'videoid': 'FEbMCBxsoWI', 'publishedat': datetime(2025, 11, 25, 5, 28, 6), 'rankno': 13, 'viewcount': 754598, 'query': '야구'},
{'videoid': 'nOJUI0PGB68', 'publishedat': datetime(2025, 12, 7, 3, 7, 46), 'rankno': 14, 'viewcount': 748349, 'query': '야구'},
{'videoid': 'uMHXIudw_w0', 'publishedat': datetime(2025, 12, 2, 10, 1, 38), 'rankno': 8, 'viewcount': 687949, 'query': '야구'}
]
target_key = '동영상 ID'
# 목록 이해 사용: data_list의 각 사전 항목에 대해 item[target_key]를 꺼냅니다.
video_ids = [data_list의 항목에 대한 항목[target_key]]
print(f"추출된 키: {target_key}")
print("모든 videoid 값:")
인쇄(video_ids)
['b5HxsaM_E2Y', 'FEbMCBxsoWI', 'nOJUI0PGB68', 'uMHXIudw_w0']
목록의 일부 사전에 대상 키가 누락된 경우(예: 일부 사전에 `videoid` 키가 없음) `item[target_key]`를 직접 사용하면 `KeyError` 오류가 발생합니다. 사전의 `.get()` 메소드나 조건문을 사용하여 안전하게 처리할 수 있습니다.
data_with_missing_key = [
{'videoid': 'A1', 'query': '축구'},
{'query': 'basketball'}, # 'videoid' 키가 누락되었습니다.
{'videoid': 'C3', 'query': '배구'}
]
target_key = '동영상 ID'
# 옵션 A: .get()을 사용하여 기본값을 None(또는 다른 값)으로 설정합니다.
safe_video_ids_A = [data_with_missing_key의 항목에 대한 item.get(target_key)]
# 출력: ['A1', 없음, 'C3']
# 옵션 B: 해당 키가 포함된 값만 추출
safe_video_ids_B = [항목에 target_key가 있는 경우 data_with_missing_key의 항목에 대한 항목[target_key]]
# 출력: ['A1', 'C3']
print(f"\n안전한 추출 결과(플랜 B): {safe_video_ids_B}")
당신은onesymbollist.values()얻은 결과는 Python 사전 뷰 객체입니다.dict_values. 목록처럼 보이지만 인덱싱하거나 수정할 수 있는 표준 목록이 아니라 동적 보기입니다.
dict_values([1763510400000, '0.00015218', '0.00015336', '0.00015415', '0.00015067', '1634523'])
표시하지 않음dict_values()태그의 내용을 얻으려면 가장 간단하고 일반적인 방법은 내장된 태그를 사용하는 것입니다.list()함수는 이를 목록으로 캐스팅합니다.
할 것이다dict_values전달list()뷰 객체의 모든 요소를 새로운 표준 목록에 즉시 복사하는 기능입니다.
# 이것이 당신이 얻은 dict_values 뷰 객체라고 가정합니다
dict_values_object = your_dictionary.values() # onesymbollist가 사전이라고 가정합니다.
# 단계: list() 함수를 사용하여 변환합니다.
결과_목록 = 목록(dict_values_object)
인쇄(결과_목록)
[1763510400000, '0.00015218', '0.00015336', '0.00015415', '0.00015067', '1634523']
불변 시퀀스를 생성하는 것이 목표라면 다음을 사용할 수 있습니다.tuple()함수는 이를 튜플로 변환합니다.
result_tuple = tuple(dict_values_object)
print(result_tuple)
(1763510400000, '0.00015218', '0.00015336', '0.00015415', '0.00015067', '1634523')
참고로 단순히 루프에서 값을 하나씩 처리하려는 경우 명시적으로 목록으로 변환할 필요가 없습니다.dict_values그 자체는 반복 가능한 객체입니다(Iterable).
# 이것이 당신이 얻은 dict_values 뷰 객체라고 가정합니다
dict_values_object = your_dictionary.values()
print("출력 요소를 하나씩:")
dict_values_object의 값:
인쇄(값)
요약하면 다음을 사용하십시오.list(your_dict.values())깨끗하고 실행 가능한 값 목록을 얻는 가장 일반적인 방법입니다.
~부터 시작하다dict_values뷰 객체에서 모든 값을 추출하고 이를 쉼표와 공백으로만 구분된 단일 문자열로 결합합니다(예:1763510400000, '0.00015218', ...), 다음 단계를 결합해야 합니다.
dict_values객체를 봅니다.", ".join()이 문자열을 연결하는 방법입니다.원래 사전의 이름이 지정되어 있다고 가정합니다.onesymbol_dict, 문자열이 아닌 값(예: 타임스탬프)을 문자열로 변환하여 사용해야 합니다..join()연결해 보세요.
onesymbol_dict = {
'시간': 1763510400000,
'열기': '0.00015218',
'닫기': '0.00015336',
'높음': '0.00015415',
'낮음': '0.00015067',
'볼륨': '1634523'
}
# 1단계 & 2: 값을 가져오고 모든 값을 문자열로 변환
# 모든 요소가 문자열인지 확인하기 위해 목록 이해를 사용합니다.
value_as_strings = [onesymbol_dict.values()의 v에 대한 str(v)]
# 3단계: ', '.join()을 사용하여 이 문자열을 결합합니다.
value_string = ", ".join(values_as_strings)
인쇄(값_문자열)
이렇게 하면 내용이 외부 대괄호나 대괄호 없이 값만 포함된 단일 문자열이 생성됩니다.dict_values상표:
1763510400000, 0.00015218, 0.00015336, 0.00015415, 0.00015067, 1634523
예상되는 예제 출력에서 타임스탬프 이외의 값에는 작은따옴표가 있습니다.1763510400000, '0.00015218', ...。
최종 출력에서 문자열 값이 작은따옴표를 유지하도록 하는 것이 목표라면 연결하는 동안 수동으로 따옴표를 추가해야 합니다. 이는 일반적으로 SQL 문이나 특정 형식에 대한 문자열을 준비할 때 필요합니다.
# 추가 단계: 정수가 아닌 값에 따옴표가 필요하다고 가정하고 따옴표를 수동으로 처리합니다.
quoted_values = []
onesymbol_dict.values()의 v에 대해:
isinstance(v, (str, float)) 또는 (isinstance(v, int) 및 v인 경우< 1000000000000): # 假設小數字串需要引號
quoted_values.append(f"'{v}'")
else:
quoted_values.append(str(v))
final_quoted_string = ", ".join(quoted_values)
print(final_quoted_string)
그러면 예상한 형식이 제공됩니다(가정).time따옴표는 필요하지 않으며 다른 숫자 문자열은 필요합니다):
1763510400000, '0.00015218', '0.00015336', '0.00015415', '0.00015067', '1634523'
isdigit()문자열에 숫자만 포함되어 있는지 확인하는 데 메서드를 사용할 수 있습니다.
# 예시
문자열 = "12345"
string.isdigit()인 경우:
print("숫자입니다")
그 외:
print("숫자가 아닙니다.")
알아채다:isdigit()소수점이나 음수 기호를 처리할 수 없습니다.
소수점이 있는 문자열을 확인해야 하는 경우 사용하기 전에 소수점을 제거하면 됩니다.isdigit()。
# 예시
문자열 = "123.45"
if string.replace(".", "").isdigit():
print("숫자입니다")
그 외:
print("숫자가 아닙니다.")
이 방법은 음수에는 작동하지 않습니다.
가장 일반적인 접근 방식은 문자열을 부동 소수점 또는 정수로 변환하고 변환이 실패할 경우 예외를 포착하는 것입니다.
# 예시
문자열 = "-123.45"
시도해 보세요:
float(string) # 대신 int(string)을 사용하여 정수를 확인할 수 있습니다.
print("숫자입니다")
ValueError 제외:
print("숫자가 아닙니다.")
정규식은 정수, 소수, 음수를 포함한 숫자와 정확하게 일치할 수 있습니다.
# 예시
다시 가져오기
문자열 = "-123.45"
패턴 = r"^-?\d+(\.\d+)?$"
re.match(패턴, 문자열)인 경우:
print("숫자입니다")
그 외:
print("숫자가 아닙니다.")
간단한 경우에는 다음을 사용하십시오.isdigit(). 더 복잡한 경우(소수 또는 음수 처리 등)에는 다음을 사용하는 것이 좋습니다.try-except또는 정규식.
f-string(형식화된 문자열 리터럴)은 Python 3.6에 도입된 강력하고 효율적인 문자열 형식화 방법입니다. 변수 및 표현식의 값을 문자열에 포함하는 간결하고 읽기 쉬운 방법을 제공합니다.
f-string의 핵심 기능은 문자열 시작 부분에 접두사를 사용하는 것입니다.f또는F, 중괄호 사용{}계산하고 표시할 내용을 포함합니다.
중괄호 안에 변수 이름을 직접 입력할 수 있습니다.
이름 = "앨리스"
나이=30
message = f"안녕하세요. 제 이름은 {name}이고 나이는 {age}세입니다."
# 출력: 안녕하세요. 제 이름은 Alice이고 30살입니다.
f-string의 장점은 유효한 Python 표현식을 중괄호 안에 넣을 수 있으며 런타임에 평가된다는 것입니다.
가격 = 19.99
세율 = 0.05
총액 = 가격 * (1 + 세금 세율)
# f-문자열 내에서 계산을 수행합니다.
result = f"세금을 포함한 총 가격은 {price * (1 + Tax_rate):.2f} 위안입니다."
# 출력: 세금을 포함한 총 가격은 20.99위안입니다.
# 통화 기능
def get_status():
"확인"을 반환
status_msg = f"시스템 상태: {get_status()}"
# 출력: 시스템 상태: OK
f-문자열 지원 및.format()콜론을 사용하는 형식 지정자 미니 언어와 동일한 방법:표현식과 형식 지정자를 구분합니다.
| 형식 코드 | 사용 | 예 | 산출 |
|---|---|---|---|
:.2f |
소수점 이하 두 자리의 부동 소수점 숫자 | f"{3.14159:.2f}" |
3.14 |
: <10 |
왼쪽 정렬, 너비 10 | f"{'Name':<10}" |
Name |
: >10 |
오른쪽 정렬, 너비 10 | f"{'Value':>10}" |
Value |
:^10 |
가운데 정렬, 너비 10 | f"{'Hi':^10}" |
Hi |
:, |
숫자 천 단위 구분 기호 | f"{1000000:,}" |
1,000,000 |
Python 3.8부터 f-string에는 변수 뒤에 등호를 추가할 수 있는 편리한 디버깅 기능이 도입되었습니다.=, 변수 이름과 해당 값을 자동으로 표시합니다.
user_id = 42
is_active = 참
debug_output = f"사용자 ID는 {user_id=}, 상태: {is_active=}"
# 출력: 사용자 ID는 user_id=42, 상태: is_active=True
'...', 안에 큰따옴표를 사용할 수 있습니다."...",그 반대도 마찬가지입니다.{{}}。\다음과 같은 문자열 형식을 나타내는 데 사용할 수 없습니다.f"{{'\n'}}"오류가 발생합니다.f-문자열의 중괄호{}내부적으로는 직접 사용할 수 있습니다.int()이 함수는 변수를 다시 정수 유형으로 변환합니다. 이것이 가장 명확하고 직접적인 방법이다.
inta = 12 # 원시 정수를 가정
float_a = inta * 2.0 # 결과는 24.0(부동 소수점 수)입니다.
# 부동 소수점 숫자를 f-문자열에서 직접 정수로 다시 변환합니다.
result_str = f"abc def {int(float_a)}"
print(f"원래 값(float_a): {float_a}")
print(f"형식화된 결과: {result_str}")
서식 미니 언어의 정수 형식 코드를 사용할 수 있습니다.d또는.0f출력 형식을 제어합니다.
:d사용:dPython은 표시될 때 값을 정수로 처리하도록 요청받습니다. 변수라면a부동 소수점 숫자인 경우 Python은 표시하기 전에 자동으로 가장 가까운 정수로 반올림합니다(계산 결과가 $24.0$이면 $24$가 표시됩니다).
float_a = 24.0
result_d = f"abc def {float_a:d}"
# 출력: abc def 24
:.0f사용:.0f값을 부동 소수점 숫자로 형식화하지만 소수점 이하 0자리가 필요함을 의미합니다. 이로 인해 결과가 표시되기 전에 반올림됩니다.
float_a = 24.0
result_0f = f"abc def {float_a:.0f}"
# 출력: abc def 24
결과가 소수점 없는 절대 정수인지 확인하는 것이 목적이라면 옵션 1을 사용하는 것이 좋습니다.
str = f"abc def {int(a)}"
파이썬에서는re.split()기능은re정규식에 정의된 구분 기호(패턴)에 따라 문자열을 분할하고 결과를 목록(목록)으로 반환하는 데 사용되는 (정규식) 모듈의 강력한 도구입니다.
re.split(pattern, string, maxsplit=0, flags=0)
pattern: 문자열을 분할하는 데 사용되는 정규식 패턴입니다.string: 잘라낼 대상 문자열입니다.maxsplit(선택 사항): 최대 절단 수를 지정합니다. 기본값 0은 절단 수에 제한이 없음을 의미합니다.flags(선택사항): 정규식의 동작을 제어하는 플래그(예:re.IGNORECASE)。정규식을 사용하여 여러 개의 또는 복잡한 구분 기호를 정의합니다.
다시 가져오기
text = "사과,바나나,오렌지-포도"
# 쉼표, 세미콜론, 하이픈을 구분 기호로 사용하세요.
결과 = re.split(r'[;,-]', 텍스트)
인쇄(결과)
# 출력: ['사과', '바나나', '오렌지', '포도']
표준 문자열 포함split()다른,re.split()여러 연속 구분 기호(예: 여러 공백)는 쉽게 처리하고 무시할 수 있습니다.
text = "워드1 워드2 워드3"
# 하나 이상의 공백 문자를 구분 기호로 일치시키려면 \s+를 사용합니다.
결과 = re.split(r'\s+', text)
인쇄(결과)
# 출력: ['Word1', 'Word2', 'Word3']
설정된 경우maxsplit, 절단 작업은 지정된 횟수만큼만 수행되며 나머지 부분은 목록에 마지막 요소로 유지됩니다.
text = "하나:둘:셋:넷"
#한번만자릅니다
결과 = re.split(r':', text, maxsplit=1)
인쇄(결과)
# 출력: ['1', '2:3:4']
괄호 안에 구분자 패턴을 넣으면(), 구분 기호 자체도 결과 목록의 요소 사이에 포함됩니다.
텍스트 = "2025-01-15"
# 보존되도록 괄호 안에 하이픈을 넣습니다.
결과 = re.split(r'(-)', text)
인쇄(결과)
# 출력: ['2025', '-', '01', '-', '15']
startswith()Python 문자열입니다(str) 객체 메서드, 문자열이 지정된 하위 문자열로 시작하는지 확인하는 데 사용됩니다.
일치하면 반환True; 그렇지 않으면 반환False。
str.startswith(prefix[, start[, end]])
prefix: 비교할 시작 문자열은 단일 문자열이거나 문자열 튜플일 수 있습니다.start(선택 사항): 판단을 시작할 원본 문자열의 인덱스 위치를 지정합니다.end(선택사항): 인덱스 위치를 지정합니다(끝 제외).부울 값: 문자열이 지정된 접두사로 시작하는 경우 반환True,그렇지 않으면False。
text = "파이썬 프로그래밍"
#기본 사용법
print(text.startswith("Py")) # 참
print(text.startswith("Java")) # 거짓
#범위 지정
print(text.startswith("thon", 2)) # True(인덱스 2에서 시작하는 것은 "thon"입니다)
# 다중 정렬
print(text.startswith(("Py", "Java", "C"))) # True, 일치하는 항목이 있기 때문에
# 대소문자를 구분하지 않음(먼저 소문자로 변환 가능)
print(text.lower().startswith("py")) # 참
URL = "https://openai.com"
url.startswith("https://")인 경우:
print("보안 연결 URL")
files = ["data1.csv", "data2.csv", "readme.txt"]
csv_files = [f for f in files if f.startswith("data")]
print(csv_files) # ['data1.csv', 'data2.csv']
문자열이 특정 텍스트로 "끝나는지" 확인하려면 다음을 사용할 수 있습니다.endswith()방법, 구문 및startswith()같은.
파일명 = "보고서.pdf"
파일 이름.endswith(".pdf")인 경우:
print("PDF 파일입니다.")
Python에서 문자열은 불변 객체입니다. 마지막 문자를 제거하려면 일반적으로 문자열 슬라이싱을 사용하여 새 문자열을 만듭니다.
text = "안녕하세요!"
#방법 1: 슬라이싱 사용
new_text = 텍스트[:-1]
print(new_text) #출력: 안녕하세요
#방법 2: rstrip()을 사용하여 특정 종료 문자 제거
text2 = "안녕하세요!!!"
new_text2 = text2.rstrip("!")
print(new_text2) #출력: 안녕하세요
#방법 3: 비어 있지 않은지 확인한 후 마지막 문자를 삭제합니다.
텍스트인 경우:
텍스트 = 텍스트[:-1]
인쇄(텍스트)
Hello
Hello
Hello
text[:-1]처음부터 두 번째 문자부터 마지막 문자까지의 하위 문자열이 제거됩니다.rstrip(chars)끝에 지정된 문자(1개로 제한되지 않음)를 제거할 수 있습니다.선행 문자를 제거하려면 다음을 사용하십시오.
text = text[1:]
s[:-1]。rstrip()。문자열이 주어지면str1, 우리는에서 찾을 수 있기를 바랍니다strA또는strB앞서 나오는 부분입니다. 예를 들어:
str1 = "Hello World, this is a test. Stop here or continue."
strA = "Stop"
strB = "continue"
얻는 것이 목표이다"Hello World, this is a test. "。
re.split()여러 키워드를 기반으로 문자열을 분할하고 첫 번째 부분을 취할 수 있습니다.
import re
def get_substring_before(text, strA, strB):
result = re.split(f"{re.escape(strA)}|{re.escape(strB)}", text, maxsplit=1)[0]
return result
str1 = "Hello World, this is a test. Stop here or continue."
strA = "Stop"
strB = "continue"
print(get_substring_before(str1, strA, strB)) # "Hello World, this is a test. "
re.search()일치하는 데 사용할 수 있습니다strA또는strB, 일치하기 전에 콘텐츠를 가져옵니다.
import re
def get_substring_before(text, strA, strB):
match = re.search(f"{re.escape(strA)}|{re.escape(strB)}", text)
return text[:match.start()] if match else text
str1 = "Hello World, this is a test. Stop here or continue."
print(get_substring_before(str1, "Stop", "continue")) # "Hello World, this is a test. "
find()가장 이른 날짜를 수동으로 검색할 수 있습니다.strA또는strB, 해당 부분을 검색합니다.
def get_substring_before(text, strA, strB):
indexA = text.find(strA)
indexB = text.find(strB)
indices = [i for i in [indexA, indexB] if i != -1]
first_index = min(indices, default=len(text))
return text[:first_index]
str1 = "Hello World, this is a test. Stop here or continue."
print(get_substring_before(str1, "Stop", "continue")) # "Hello World, this is a test. "
re.split()가장 간단하고 단일 검색에 적합합니다.re.search()보다 유연한 정규 매칭을 제공합니다.find()이 방법은 가장 효율적이며 간단한 문자열 처리에 적합합니다.값 = ["str1", "str2", 123, "str3", 456]
s = ", ".join(값의 v에 대한 str(v))
print(s) # 출력: str1, str2, 123, str3, 456
def Join_values(*args, sep=", "):
sep.join(args의 v에 대해 str(v))을 반환합니다.
print(join_values("str1", "str2", 88, "str3"))
# 출력: str1, str2, 88, str3
데이터 = {
"str1": "안녕하세요",
"str2": "세계",
"int1": 123,
"str3": "알았어"
}
# 키별로 정렬한 후 참여
s = ", ".join(str(data[k]) for k in sorted(data.keys()))
print(s) # hello, world, 123, ok
s = ", ".join(f"{k}={v}" for k, v in data.items())
인쇄
# 출력: str1=hello, str2=world, int1=123, str3=ok
rows = [
{"str1": "A", "int1": 10},
{"str1": "B", "int1": 20},
]
for row in rows:
print(", ".join(str(v) for v in row.values()))
# A, 10
# B, 20
def Join_values(values, sep=", ", quoted=False):
인용된 경우:
# 전체 작은따옴표 ' '를 사용합니다.
return sep.join(f"'{v}'" for v 값)
그 외:
return sep.join(값의 v에 대해 str(v))
값 = ["str1", "str2", 88, "str3"]
print(join_values(values, quoted=False))
# 출력: str1, str2, 88, str3
print(join_values(values, quoted=True))
# 출력: 'str1', 'str2', '88', 'str3'
def join_args(*args, sep=", ", quoted=False):
if quoted:
return sep.join(f"‘{v}’" for v in args)
return sep.join(str(v) for v in args)
print(join_args("str1", "str2", 88, "str3", quoted=True))
# ‘str1’, ‘str2’, ‘88’, ‘str3’
data = {"str1": "hello", "str2": "world", "int1": 123}
print(join_values(data.values(), quoted=True))
# ‘hello’, ‘world’, ‘123’
def join_key_value(d, sep=", ", quoted=False):
if quoted:
return sep.join(f"{k}=‘{v}’" for k, v in d.items())
return sep.join(f"{k}={v}" for k, v in d.items())
print(join_key_value(data, quoted=True))
# str1=‘hello’, str2=‘world’, int1=‘123’
파이썬re.match문자열의 시작 부분부터 일치시키는 데 사용되는 정규식 모듈의 함수입니다.
일치가 성공하면Match물체; 그렇지 않으면 반환None。
re.match(pattern, string, flags=0)
매개변수 설명:
pattern: 일치시킬 정규식입니다.string: 확인할 문자열입니다.flags: 일치 동작을 수정하는 데 사용되는 선택적 매개변수입니다. 예를 들어re.IGNORECASE。group(n):처음으로 돌아가기n캡처된 하위 그룹,n=0전체 일치 항목을 반환합니다.start(): 경기의 시작 위치를 반환합니다.end(): 경기의 종료 위치를 반환합니다.span(): 일치하는 범위(시작, 끝)를 반환합니다.다시 가져오기
#문자열 정의
text = "123 헬로월드!"
# 처음부터 숫자를 일치시키려면 re.match를 사용하세요.
일치 = re.match(r"(\d+)\s+(.*)", 텍스트)
일치하는 경우:
print(f"전체 일치 결과: {match.group(0)}") # 123 Hello World!
print(f"숫자 부분: {match.group(1)}") # 123
print(f"텍스트 부분: {match.group(2)}") # Hello World!
그 외:
print("일치 실패")
전체 일치 결과: 123 Hello World!
숫자 부분: 123
텍스트 부분: Hello World!
re.match문자열의 시작 부분에서만 일치하고, 시작 부분이 일치하지 않으면 반환None。re.search또는re.findall。정규식(줄여서 Regex)은 문자열 일치 규칙을 설명하는 데 사용되는 구문입니다. 문자열을 검색, 교체 또는 확인하는 데 자주 사용됩니다.
파이썬에서re모듈에서는pattern이것이 이러한 규칙을 정의하는 핵심 부분입니다.
\d: 임의의 숫자(0-9)와 일치합니다.\D: 숫자가 아닌 모든 항목과 일치합니다.\w: 모든 단일 문자(문자, 숫자, 밑줄)와 일치합니다.\W: 단일 문자가 아닌 모든 문자와 일치합니다.\s: 모든 공백 문자(공백, 탭 등)와 일치합니다.\S: 공백이 아닌 모든 문자와 일치합니다..: 개행 문자를 제외한 일치(\n) 단일 문자는 제외됩니다.*: 이전 표현식과 0회 이상 일치합니다.+: 이전 표현과 1번 이상 일치합니다.?: 이전 표현식과 0번 또는 1번 일치합니다.{n}: 이전 표현식과 정확히 n번 일치합니다.{n,}: 이전 표현식을 n번 이상 일치시킵니다.{n,m}: 이전 표현식과 최소 n회, 최대 m회 일치합니다.^: 문자열의 시작 부분과 일치합니다.$: 문자열의 끝과 일치합니다.\b: 단어 경계(예: 단어의 시작 또는 끝)와 일치합니다.\B: 단어가 아닌 경계와 일치합니다.(...):그룹, 괄호 안의 내용을 캡처합니다.|: 논리적 "또는"(예:a|b성냥a또는b。(?:...): 그룹화되지만 콘텐츠를 캡처하지는 않습니다.(?=...): 앞으로 일치 항목이 지정된 콘텐츠로 이어져야 합니다.(?!...): 부정적인 탐색, 지정된 콘텐츠가 일치 뒤에 올 수 없습니다.(?<=...): Forward Lookback, 일치는 지정된 내용이 선행되어야 합니다.(?<!...): 부정적인 룩백으로, 지정된 콘텐츠가 매칭보다 선행될 수 없습니다.다시 가져오기
# 예시 1: 숫자로 시작하는 콘텐츠 일치
패턴 = r"^\d+"
텍스트 = "123abc"
일치 = re.match(패턴, 텍스트)
일치하는 경우:
print(f"일치 결과: {match.group()}") # 출력: 123
#예 2: 숫자 뒤의 텍스트 일치
패턴 = r"(\d+)\s+(.*)"
text = "123 헬로월드"
일치 = re.match(패턴, 텍스트)
일치하는 경우:
print(f"숫자 부분: {match.group(1)}") # 출력: 123
print(f"텍스트 부분: {match.group(2)}") # 출력: Hello World
re.search()문자열에서 정규식과 일치하는 첫 번째 항목을 검색하고 반환하는 데 사용됩니다.Match일치하는 항목이 없으면 반환되는 객체None。
다시 가져오기
text = "안녕하세요 2024!"
일치 = re.search(r"\d+", 텍스트)
일치하는 경우:
print("발견된 번호:", match.group()) # 2024
언제re.search()일치하는 항목이 발견되면 반환됩니다.Match객체는 다음 방법을 통해 정보에 액세스할 수 있습니다.
group(): 일치하는 문자열을 반환합니다.start(): 일치하는 시작 인덱스end():일치의 끝 인덱스span():반환(시작, 끝) 인덱스 범위다시 가져오기
text = "파이썬 3.10은 훌륭해요!"
일치 = re.search(r"\d+\.\d+", 텍스트)
일치하는 경우:
print("일치하는 내용:", match.group()) # 3.10
print("시작 인덱스:", match.start()) # 7
print("끝 인덱스:", match.end()) # 11
print("범위:", match.span()) # (7, 11)
괄호를 통해()그룹을 만들어서 사용하려면group(n)해당 일치하는 콘텐츠를 추출합니다.
다시 가져오기
text = "John Doe, 나이: 25"
match = re.search(r"(\w+) (\w+), 연령: (\d+)", text)
일치하는 경우:
print("성:", match.group(1)) # 존
print("name:", match.group(2)) # Doe
print("나이:", match.group(3)) # 25
re.search()처음으로 일치하는 결과만 반환되지만,re.findall()일치하는 모든 결과가 반환됩니다.
import re
text = "Price: $10, Discount: $2, Tax: $1"
match = re.search(r"\$\d+", text)
print("re.search:", match.group()) # $10
matches = re.findall(r"\$\d+", text)
print("re.findall:", matches) # ['$10', '$2', '$1']
re.search()첫 번째로 일치하는 결과를 찾는 데 적합하며 다음 용도로 사용할 수 있습니다.Match자세한 정보를 얻기 위한 객체입니다. 일치하는 결과가 여러 개인 경우 다음을 사용하세요.re.findall()。
정규 표현식에서는(...)일치하는 콘텐츠가 캡처되어 다음 위치에 저장됩니다.group(n), 그러나 캡처 그룹은 아님(?:...)조직구조에만 사용되며, 그룹번호에는 영향을 미치지 않으므로 매칭이 더 빠릅니다.
정규식에 사용되는 경우()영향을 미칠 일치 조건을 구성합니다.group(n)숫자. 사용(?:...)이렇게 하면 그룹 인덱스가 변경되지 않은 상태로 유지됩니다.
import re
text = "2024-03-12"
pattern = r"(\d{4})-(?:\d{2})-(\d{2})"
match = re.search(pattern, text)
print(match.group(1)) # 2024
print(match.group(2)) # 12
사용(?:...|...)허락할 수 있다|연산자는 일치하는 콘텐츠에 영향을 주지만 그룹 액세스에는 영향을 주지 않습니다.
import re
text = "bar123"
pattern = r"(?:foo|bar|baz)\d+"
match = re.search(pattern, text)
print(match.group()) # bar123
Chrome 매개변수를 구문 분석할 때 다음을 사용하세요.(?:...)이렇게 하면 일치하는 형식이 그룹 번호에 영향을 주지 않습니다.
import re
cmdline = '--user-data-dir="C:\\Users\\moirg\\AppData\\Local\\Google\\Chrome\\User Data"'
match = re.search(r'--user-data-dir=(?:"([^"]+)"|(\S+))', cmdline)
user_data_dir = match.group(1) or match.group(2)
print(user_data_dir) # C:\Users\moirg\AppData\Local\Google\Chrome\User Data
(?:...)정규식의 성능을 향상시키고 그룹 인덱스에 영향을 주지 않으며 다음에 적합합니다.|작업 및 특정 조건 일치를 통해 코드가 더욱 효율적이고 명확해집니다.
import datetime
now = datetime.datetime.now()
print(now)
dt = datetime.datetime(2025, 7, 2, 14, 30, 0)
print(dt)
now = datetime.datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)
dt_str = "2025-07-02 14:30:00"
parsed = datetime.datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")
print(parsed)
now = datetime.datetime.now()
delta = datetime.timedelta(days=7)
next_week = now + delta
print(next_week)
today = datetime.date.today()
print(today)
dt1 = datetime.datetime(2025, 7, 1)
dt2 = datetime.datetime(2025, 7, 2)
print(dt1 < dt2)
dt1 = datetime.datetime(2025, 7, 1, 12, 0, 0)
dt2 = datetime.datetime(2025, 7, 2, 14, 30, 0)
diff = dt2 - dt1
print(diff)
print(diff.total_seconds())
오늘 = datetime.date.today()
print(today.weekday()) # 0 = 월요일, 6 = 일요일
하나의 datetime 객체에 시간대가 없고(순진) 다른 객체에 시간대(인식)가 있어서 이를 빼면 다음이 생성됩니다.
TypeError: can't subtract offset-naive and offset-aware datetimes
from datetime import datetime
def is_aware(dt):
return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
def is_naive(dt):
return not is_aware(dt)
dt1 = datetime.now() # naive
dt2 = datetime.now().astimezone() # aware
print(is_naive(dt1), is_aware(dt1))
print(is_naive(dt2), is_aware(dt2))
시간대가 다른 상황이나 정확한 시간 계산이 필요한 경우에 적합합니다.
날짜/시간 가져오기 날짜/시간, 시간대
sql_dt = sql_dt.replace(tzinfo=timezone.utc) # SQL 데이터 전송 인식
now_dt = datetime.now(timezone.utc) # 현재 시간에 대한 인식을 사용합니다.
diff = now_dt - sql_dt
인쇄(diff.total_seconds())
sql_dt = sql_dt.replace(tzinfo=None)
now_dt = datetime.now()
diff = now_dt - sql_dt
Python에서는 내장 모듈을 사용할 수 있습니다.statistics~의stdev()또는pstdev()표본 표준편차 또는 모집단 표준편차를 계산합니다.
수입통계
비율 = [2.3, 2.8, 3.1, 2.5, 3.0]
# 평균
평균 = 합계(비율) / len(비율)
#표본 표준편차(n-1)
std_sample = 통계.stdev(비율)
#행렬 표준편차(n)
std_population = 통계.pstdev(비율)
print(f"평균: {평균:.2f}")
print(f"표본 표준편차: {std_sample:.3f}")
print(f"인구 표준편차: {std_population:.3f}")
평균: 2.74
표본 표준편차: 0.303
모집단 표준편차: 0.271
의지하고 싶지 않다면statistics모듈에서는 수학 공식을 사용하여 직접 계산할 수 있습니다.
비율 = [2.3, 2.8, 3.1, 2.5, 3.0]
평균 = 합계(비율) / len(비율)
#표준편차(인구)
분산 = sum((x - 평균) ** 비율 x의 경우 2) / len(비율)
std_dev = 분산 ** 0.5
print(f"표준편차: {std_dev:.3f}")
표준편차: 0.271
statistics.stdev(): 표본 표준편차(다음으로 나눔)n-1)statistics.pstdev(): 상위 표준편차(으로 나눈 값)n)pstdev()stdev()avg = sum(data) / len(data)statistics.stdev(data)statistics.pstdev(data)# ANSI 색상 코드 예
print("\033[31m 빨간색 텍스트\033[0m")
print("\033[32m 녹색 텍스트\033[0m")
print("\033[33myellow text\033[0m")
print("\033[34m 파란색 텍스트\033[0m")
print("\033[35m 보라색 텍스트\033[0m")
print("\033[36m 청록색 텍스트\033[0m")
print("\033[37m 흰색 텍스트\033[0m")
print("\033[1;31m 굵은 빨간색 텍스트\033[0m")
print("\033[42m 녹색 배경 텍스트\033[0m")
# 형식: \033[스타일; 전경색; 배경색 m
# 스타일: 0=기본값, 1=굵게, 4=밑줄
# 전경색 : 30~37
# 배경색 : 40~47
print("\033[1;33;44m 굵은 노란색 텍스트 + 파란색 배경\033[0m")
def color_text(텍스트, color_code):
f"\033[{color_code}m{text}\033[0m" 반환
print(color_text("경고!", "1;31")) # 굵은 빨간색
print(color_text("성공!", "1;32")) # 굵은 녹색
importsys
sys.stdout.isatty()인 경우:
print("터미널은 ANSI 색상을 지원할 수 있습니다.")
그 외:
print("색상을 지원하지 않는 파일이나 출력 환경일 수 있습니다.")
수입 칼라마
colorama.init()
print("\033[32m이 텍스트는 녹색이어야 합니다\033[0m")
def support_ansi():
시도해 보세요:
print("\033[31m 테스트 레드\033[0m")
True를 반환
제외:
거짓을 반환
print("ANSI가 지원됩니다" if presents_ansi() else "ANSI는 지원되지 않습니다")
colorama。파이썬에서는input()기능 자체는 지원하지 않습니다Tab자동으로 완료됩니다.
이 기능을 달성하려면 다음을 결합할 수 있습니다.readline사용자가 사용할 수 있도록 하는 모듈Tab자동 완성을 수행합니다(Bash 또는 IPython과 유사).
readline 가져오기
# 완성할 수 있는 문자열 목록을 정의합니다.
WORDS = ['사과', '바나나', '체리', '포도', '오렌지', '수박']
def 완성자(텍스트, 상태):
"""자동 완성 기능: 입력 접두사를 기준으로 사용 가능한 문자열을 비교합니다."""
options = [w.startswith(text)인 경우 WORDS의 w에 대한 w]
상태 < 렌(옵션):
반품 옵션[상태]
그 외:
반환 없음
# 완성 기능 활성화
readline.set_completer(완성자)
readline.parse_and_bind('탭: 완료')
# 사용자 입력(Tab 지원)
user_input = input("과일 이름을 입력하세요(Tab을 눌러 완료할 수 있습니다): ")
print(f"입력한 내용은 다음과 같습니다: {user_input}")
readline.set_completer()자동 완성 논리를 설정합니다.readline.parse_and_bind('tab: complete')허락하다Tab키가 자동 완성을 트리거합니다.completer(text, state):
text현재 입력된 텍스트입니다.state일치하는 항목(0, 1, 2...)을 나타냅니다.None。현재 컨텍스트나 동적 콘텐츠를 기반으로 완성 목록을 업데이트할 수도 있습니다.
readline 가져오기
def Dynamic_completer(텍스트, 상태):
current_words = ['고양이', '자동차', '개', '오리', '사슴']
옵션 = [w.startswith(text)인 경우 current_words의 w에 대한 w]
상태 < 렌(옵션):
반품 옵션[상태]
반환 없음
readline.set_completer(동적_완성자)
readline.parse_and_bind('탭: 완료')
command = input("동물 이름을 입력하세요: ")
print("입력하신 내용:", command)
readline모듈은Linux / macOS위의 사전 설정을 사용할 수 있습니다.pip install pyreadline3
readline모듈은 다음을 허용합니다.input()탭 완성을 지원합니다.pyreadline3전부.가장 일반적인 루프는 고정된 횟수 또는 시퀀스를 실행하는 데 사용됩니다.
# 0부터 4까지
범위 내의 i에 대해(5):
인쇄(i) #0,1,2,3,4
#시작점, 끝점 및 단계 크기 지정
i가 범위(2, 10, 2)에 있는 경우:
인쇄(i) #2,4,6,8
목록, 문자열, 사전 등을 직접 반복합니다.
과일 = ["사과", "바나나", "체리"]
과일 속의 과일:
인쇄물(과일)
"hello"의 ch에 대해:
인쇄(채널)
#사전 반복
사람 = {"이름": "톰", "나이": 25}
키의 경우 person.items()의 값:
인쇄(키, 값)
조건이 True일 때 항상 실행됩니다.
count = 0
while count < 5:
print(count)
count += 1
루프 프로세스를 제어합니다.
범위(10)에 있는 i의 경우:
내가 == 3인 경우:
계속 # 이번에는 건너뛰기
내가 == 7인 경우:
break # 일찍 종료
인쇄(i)
원으로 돌아가서 다시 원에 넣으세요.
for i in range(3):
for j in range(2):
print(f"i={i}, j={j}")
동안 또는 동안에 추가할 수 있습니다.else, "정상 완료(중단 없음)"만 실행됩니다.
범위 내의 i에 대해(5):
인쇄(i)
그 외:
print("루프가 정상적으로 종료됩니다.")
간결한 작성 방법을 사용하면 루프를 완성하고 한 줄에 목록을 생성할 수 있습니다.
squares = [x**2 for x in range(5)]
print(squares) # [0,1,4,9,16]
for in range(): 고정된 시간이나 순서에 적합합니다.반복 가능한 객체의 경우: 목록, 문자열, 사전 처리에 적합합니다.while: 횟수가 무한하고 조건에 따라 끝나는 루프에 적합합니다.break / continue / else: 루프 프로세스를 제어합니다.Python은 프로그램 충돌을 방지하기 위해 프로그램 실행 중에 발생하는 오류를 가로채고 처리하기 위해 try...out 문을 사용합니다.
시도해 보세요:
# 예외가 발생할 수 있는 코드
결과=10/0
ZeroDivisionError 제외:
# 특정 예외가 발생했을 때 실행되는 코드
print("제수는 0이 될 수 없습니다.")
e와 같은 예외를 제외하고:
#다른 모든 유형의 예외 포착
print(f"오류가 발생했습니다: {e}")
그 외:
# try 블록에서 예외가 발생하지 않으면 실행됩니다.
print("정상적으로 작동합니다.")
마지막으로:
# 예외 발생 여부에 관계없이 실행됩니다.
print("리소스를 정리하거나 파일을 닫습니다.")
여러 오류 유형을 동시에 처리하기 위해 예외에 튜플을 사용할 수 있습니다.
시도해 보세요:
# 작업 수행
통과
제외(ValueError, TypeError):
print("입력한 데이터 유형이나 값이 올바르지 않습니다.")
논리적 요구 사항에 따라 예외를 수동으로 트리거하려면 raise 키워드를 사용하세요.
age = -1
if age < 0:
raise ValueError("年齡數值不可為負數")
클래스 MyClass:
def __init__(자체, 값):
self.value = 가치
def 디스플레이(자체):
print(f"값: {self.value}")
obj = MyClass(10)
obj.display() # 출력: 값: 10
정적 메서드는 `@staticmethod` 데코레이터를 사용하여 정의되며 카테고리 및 개체와 관련이 없습니다. 범주 속성이나 개체 속성에 액세스할 수 없습니다. 일부 악기 기능에 적용됩니다.
클래스 MyClass:
@staticmethod
정의 추가(a, b):
a + b를 반환
결과 = MyClass.add(5, 3)
print(result) # 출력: 8
클래스 메서드는 `@classmethod` 데코레이터를 사용하여 정의되며 첫 번째 매개 변수는 클래스 자체(일반적으로 `cls`라고 함)이며 클래스 특성에 액세스할 수 있습니다.
클래스내클래스:
개수 = 0
@classmethod
def increment_count(cls):
cls.count += 1
MyClass.increment_count()
print(MyClass.count) # 출력: 1
Python은 클래스 상속을 지원합니다. 하위 클래스는 상위 클래스의 속성과 메서드를 상속하고 상위 클래스 메서드를 재정의할 수 있습니다.
클래스 상위:
데프 인사(자신):
print("부모님께서 안녕하세요!")
클래스 아동(부모):
데프 인사(자신):
print("안녕하세요 from Child!")
obj = 자식()
obj.greet() # 출력: Hello from Child!
카테고리 속성은 전체 카테고리에 속하며 모든 개체에서 공유됩니다. 객체 속성은 각 객체에 속합니다.
클래스내클래스:
class_attr = "나는 클래스 속성입니다"
def __init__(자체, 값):
self.instance_attr = 값
obj1 = MyClass(10)
obj2 = MyClass(20)
print(MyClass.class_attr) # 출력: 나는 클래스 속성입니다.
print(obj1.instance_attr) # 출력: 10
print(obj2.instance_attr) # 출력: 20
Python의 모든 클래스는 기본적으로 `__str__` 및 `__eq__`와 같은 몇 가지 기본 메서드를 제공하는 내장 기본 클래스인 `object`에서 상속됩니다.
클래스 MyClass(객체):
def __init__(자체, 값):
self.value = 가치
def __str__(자체):
f"값이 {self.value}인 MyClass"를 반환합니다.
obj = MyClass(5)
print(obj) # 출력: 값이 5인 MyClass
Python에서 클래스 상속을 사용하면 하위 클래스(파생 클래스)가 상위 클래스(기본 클래스)의 속성과 메서드를 상속하여 코드 재사용을 달성할 수 있습니다. 예를 들어:
클래스 상위:
데프 인사(자신):
print("부모님께서 안녕하세요!")
클래스 아동(부모):
통과
c = 자식()
c.greet() # 출력: Hello from Parent!
하위 클래스는 상위 클래스의 메서드를 재정의(Override)하고 해당 함수를 다시 작성할 수 있습니다.
클래스 상위:
데프 인사(자신):
print("부모님께서 안녕하세요!")
클래스 아동(부모):
데프 인사(자신):
print("안녕하세요 from Child!")
c = 자식()
c.greet() # 출력: Hello from Child!
하위 클래스에서는 `super()`를 통해 상위 클래스의 메서드를 호출하고 상위 클래스의 동작을 확장할 수 있습니다.
클래스 상위:
데프 인사(자신):
print("부모님께서 안녕하세요!")
클래스 아동(부모):
데프 인사(자신):
슈퍼().인사()
print("안녕하세요 from Child!")
c = 자식()
c.인사()
# 출력:
# 안녕하세요 학부모님!
# 안녕하세요 차일드입니다!
Python은 다중 상속을 지원하며 하위 클래스는 동시에 여러 부모 클래스를 상속할 수 있습니다.
클래스 Parent1:
데프 인사(자신):
print("Parent1님 안녕하세요!")
클래스 Parent2:
데프 인사(자신):
print("Parent2님 안녕하세요!")
클래스 하위(Parent1, Parent2):
통과
c = 자식()
c.greet() # 출력: Hello from Parent1! (상속 순서에 따라)
다중 상속은 MRO(Method Resolution Order)를 사용하여 메서드의 해결 순서를 결정합니다. 이는 `__mro__` 속성을 사용하여 확인할 수 있습니다:
인쇄(Child.__mro__) # 출력: (, , , )
`abc` 모듈을 사용하여 추상 기본 클래스를 정의하여 하위 클래스가 특정 메서드를 구현하도록 합니다.
abc에서 ABC 가져오기, 추상 메서드
클래스 AbstractParent(ABC):
@추상방법
데프 인사(자신):
통과
클래스 Child(AbstractParent):
데프 인사(자신):
print("안녕하세요 from Child!")
c = 자식()
c.greet() # 출력: Hello from Child!
클래스ClassB:
데프 인사(자신):
print("ClassB에서 안녕하세요!")
# ClassB에서 상속된 임시 클래스를 동적으로 생성합니다.
TempClass = type('TempClass', (ClassB,), {
'greet': 람다 self: (print("Hello from TempClass!"), super(TempClass, self).greet())[0]
})
#인스턴스 생성 및 테스트
온도 = TempClass()
temp.greet()
type('TempClass', (ClassB,), {...})greet방법은 새 메시지를 먼저 인쇄한 다음 전달하는 것입니다.super()상위 카테고리에 전화하기greet。
Hello from TempClass!
Hello from ClassB!
두 가지 범주가 있다고 가정AClass그리고BClass, 이름과 매개변수가 동일한 함수가 있습니다.
우리는 메인 프로그램 로직을 수정하지 않고도 사용할 카테고리를 쉽게 전환할 수 있기를 원합니다.
클래스 A클래스:
def 프로세스(자기, 데이터):
print(f"A클래스 처리: {data}")
def 결과(자기):
"AClass의 결과"를 반환합니다.
클래스 B클래스:
def 프로세스(자기, 데이터):
print(f"BClass 처리: {data}")
def 결과(자기):
"BClass의 결과"를 반환합니다.
# 설정을 통해 사용할 카테고리를 제어할 수 있습니다.
USE_A = 참
#동적 카테고리 선택
SelectedClass = USE_A가 아니면 BClass인 경우 AClass
# 인스턴스를 생성하고 사용
obj = 선택클래스()
obj.process("테스트 데이터")
인쇄(obj.result())
AClass 처리: 테스트 데이터
AClass의 결과
BClass 처리: 테스트 데이터
BClass의 결과
def get_class(이름):
매핑 = {
"A": A 클래스,
"B": B클래스
}
return mapping.get(name, AClass) # 기본값은 AClass입니다.
# 동적 선택
cls = get_class("B")
obj = cls()
obj.process("테스트 데이터")
파이썬에서는반드시 필수는 아님C++ 또는 Java처럼 작성됨abstract class.
Python은 "Duck Typing"을 채택했습니다. 객체가 동일한 메서드 이름과 동작을 갖는 한 호환되는 것으로 간주될 수 있습니다.
클래스 A클래스:
def 프로세스(자기, 데이터):
print(f"A클래스 처리: {data}")
클래스 B클래스:
def 프로세스(자기, 데이터):
print(f"BClass 처리: {data}")
데프 실행(obj):
obj.process("data") # 이 메소드가 있는 한 유형을 지정할 필요가 없습니다.
실행(A클래스())
실행(BClass())
A클래스 처리: 데이터
BClass 처리: 데이터
Python은 유형을 강제하지 않지만 팀 개발이나 대규모 프로젝트에서 인터페이스를 명확하게 정의하려는 경우 다음을 사용할 수 있습니다.abc개조.
abc에서 ABC 가져오기, 추상 메서드
클래스 BaseClass(ABC):
@추상방법
def 프로세스(자기, 데이터):
통과
클래스 AClass(BaseClass):
def 프로세스(자기, 데이터):
print(f"A클래스 처리: {data}")
클래스 BClass(BaseClass):
def 프로세스(자기, 데이터):
print(f"BClass 처리: {data}")
# BaseClass()는 추상 메서드가 구현되지 않았기 때문에 오류를 보고합니다.
abc개조.파이썬에서는기준 치수일반적으로 파일 확장자를 갖는 프로그램 코드가 포함된 파일입니다..py끝. 모듈은 함수, 범주, 변수를 정의할 수 있으며 재사용 및 프로그램 구조화를 용이하게 하기 위해 실행 가능한 코드를 포함할 수도 있습니다.
파이썬을 통해import모듈을 소개하는 키워드입니다. 예:
수학 가져오기
print(math.sqrt(16)) # 출력 4.0
개발자는 자신만의 모드를 만들 수 있습니다. 예를 들어mymodule.py:
# mymodule.py
def greet(name):
return f"Hello, {name}!"
다른 프로그램 파일에서 사용:
import mymodule
print(mymodule.greet("Alice"))
os: 운영체제 관련 작업을 처리합니다.sys: Python 인터프리터 관련 정보에 액세스합니다.datetime: 처리 날짜 및 시간입니다.math: 수학적인 기능을 제공합니다.random: 난수를 생성합니다.파이썬에서는패키지모듈을 구성하는 방법입니다. 패키지는 여러 모듈을 포함하는 디렉터리로, 계층 구조를 통해 프로그램을 더 쉽게 관리하고 유지 관리할 수 있습니다.
__init__.pyarchive (Python 3.3+에서는 생략되었지만 제품군을 명확하게 정의하는 데 도움이 되도록 추가됨).라는 이름의 파일을 생성합니다.mypackage키트:
mypackage/
│── __init__.py
│── module1.py
└── module2.py
module1.py예:
def add(a, b):
return a + b
module2.py예:
def multiply(a, b):
return a * b
mypackage.module1 가져오기
mypackage.module2 가져오기
print(mypackage.module1.add(2, 3)) # 출력 5
print(mypackage.module2.multiply(2, 3)) # 출력 6
mypackage.module1에서 가져오기 추가
mypackage.module2에서 곱하기 가져오기
print(add(10, 5)) # 출력 15
print(multiply(10, 5)) # 출력 50
Python에서 현재 모듈의 값을 얻으려면패키지 이름, 특수 변수를 사용할 수 있습니다__package__. 이것과__module__현재 모듈 이름을 얻는 개념은 비슷합니다.
mypackage/
│── __init__.py
└── submodule.py
submodule.py콘텐츠:
print("__name__:", __name__)
print("__package__:", __package__)
print("__module__:", __module__)
다른 프로그램에서 다음과 같이 사용하는 경우import mypackage.submodule가져오기, 출력은 대략 다음과 같습니다.
__name__: mypackage.submodule
__package__: mypackage
__module__: __main__
__name__: 전체 모듈 이름입니다.__package__: 현재 모듈이 속한 패키지 이름입니다. 최상위 모듈인 경우 빈 문자열이 됩니다.__module__: 일반적으로 클래스나 함수 정의에 사용되어 해당 클래스가 정의된 모듈을 나타냅니다.__package__패키지 경로를 확인하는 데 도움을 주세요.Python 패키지 버전을 확인하는 두 가지 주요 방법은 터미널(명령줄)을 통하거나 Python 코드에서 실행하는 것입니다. 이는 환경이 프로젝트 요구 사항을 충족하는지 확인하는 데 도움이 될 수 있습니다.
이는 가장 빠른 방법이며 Python 대화형 환경에 들어갈 필요가 없습니다.
pip 쇼 패키지 이름(예를 들어pip show pandas)。pip list。핍 목록 | findstr "패키지 이름"(윈도우즈) 또는핍 목록 | grep "패키지 이름" (Linux/Mac)。콘다 목록 패키지 이름。프로그램 실행 시 버전을 확인해야 하는 경우 다음 두 가지 방법을 사용할 수 있습니다.
import pandas
print(pandas.__version__)
from importlib.metadata import version
print(version('pandas'))
| 방법 | 지침/코드 | 적용 가능한 상황 |
|---|---|---|
| 핍 명령 | pip show |
설치 경로, 작성자, 종속성 등의 자세한 정보를 봅니다. |
| 핍 목록 | pip list |
현재 환경의 모든 패키지와 버전에 대한 빠른 개요를 확인하세요. |
| 내부 속성 | .__version__ |
스크립트가 실행되는 동안 논리적인 판단을 내리세요. |
| Metadata | version() |
전체 제품군을 로드하지 않고 확인하는 표준화된 방법입니다. |
때로는 문제가 제품군에 있는 것이 아니라 Python 인터프리터 자체에 있는 경우도 있습니다.
python --versionimport sys
print(sys.version)
pip list표시된 버전은 VS Code에서 실행된 버전과 다릅니다. 확인하시기 바랍니다Interpreter선택이 올바른지 여부.importlib제거된 패키지를 확인하면 오류가 발생합니다.PackageNotFoundError。pip show대소문자를 구분하지 않지만 일부 코드 논리에는 정확한 이름이 필요할 수 있습니다.Python에서는 다음을 통해 클래스 객체에 액세스할 수 있습니다.cls.__module__카테고리를 정의하는 모듈의 이름을 찾아 다음을 사용하십시오.sys.modules모듈 객체를 가져와서 마지막으로 읽습니다.__package__패키지 이름을 가져오는 속성입니다.
importsys
# 카테고리가 mypackage.submodule에 정의되어 있다고 가정합니다.
클래스 MyClass:
통과
# 카테고리가 속한 모듈의 이름을 가져옵니다.
module_name = MyClass.__모듈__
print("모듈 이름:", module_name)
# 모듈 객체를 얻습니다
모드 = sys.modules[모듈_이름]
# 모듈 객체에서 패키지 이름을 가져옵니다.
print("패키지 이름:", mod.__package__)
모듈 자체는 객체이며 직접 액세스할 수 있습니다.__package__재산.
수학 가져오기
mypackage.submodule을 하위로 가져오기
# 수학은 표준 함수 라이브러리 모듈이고 패키지가 없으므로 __package__는 빈 문자열입니다.
print("math.__package__:", math.__package__)
# 맞춤형 키트용 모듈
print("sub.__package__:", sub.__package__)
모듈 이름: mypackage.submodule
패키지 이름: mypackage
수학.__패키지__:
sub.__package__: 내패키지
카테고리 → __모듈__ → sys.modules[...] → __패키지__모듈 객체 → __package__직접 획득Python 파일이 직접 실행될 때 해당 모듈 이름은 다음과 같습니다.__main__. 이것은 단지cls.__module__원본 파일 이름과 경로를 가져올 수 없습니다.
프로젝트 구조가 다음과 같다고 가정합니다.
/프로젝트
|-- test_runner.py <-- 직접 실행하는 파일(__main__으로 처리됩니다)
|-- 테스트/
|-- db_test.py <-- DbCmdAgent를 정의하는 파일
`test_runner.py`에서 다음 코드를 실행하면:
test.db_test에서 DbCmdAgent 가져오기
Agent_obj = DbCmdAgent(...) # 인스턴스화
# 현재 cls.__module__은 여전히 'test.db_test'입니다(올바른 모듈 이름).
그러나 `test_runner.py`에 카테고리를 정의하는 경우:
# test_runner.py의 내용
클래스 DbCmdAgent:
통과
Agent_obj = DbCmdAgent()
#이때 cls.__module__ == '__main__' (잘못된 모듈 이름)
이는 정보를 얻고 있는 클래스가 `__main__`으로 실행되는 파일에 정의되어 있음을 나타냅니다.
inspect모듈은 파일 경로를 직접 얻을 수 있습니다카테고리가 `__main__`에 정의되어 있는지 여부에 관계없이 `__module__` 속성을 우회하고 사용할 수 있습니다.inspect이 카테고리에 해당하는 소스 코드 파일 경로를 얻기 위한 모듈입니다. 이는 보다 안정적이고 일반적인 방법입니다.
수입 검사
수입 OS
# --- 시뮬레이션 상황: __main__(현재 실행 중인 스크립트)에 정의된 카테고리 ---
클래스 DbCmdAgent:
"""이 범주는 현재 실행 중인 기본 스크립트에 정의되어 있습니다."""
def __init__(자기, 데이터):
self.data = 데이터
Agent_obj = DbCmdAgent("some_data")
def get_class_location_robust(obj):
"""
__module__ == '__main__' 문제를 우회하려면 Inspection.getfile을 사용하십시오.
"""
cls = 유형(obj)
# 1. 카테고리를 정의하는 파일 경로를 가져오려면 Inspection.getfile()을 사용하십시오.
시도해 보세요:
file_path=inspect.getfile(cls)
# 2. 파일 이름과 디렉터리 가져오기
file_name = os.path.basename(파일_경로)
디렉토리 = os.path.dirname(file_path)
py_name = os.path.splitext(파일_이름)[0]
# 3. __module__이 __main__인 경우 더 많은 컨텍스트를 제공하기 위해 이를 아카이브 이름으로 대체합니다.
module_name = cls.__모듈__
module_name == '__main__'인 경우:
module_name = py_name # db_test 또는 test_runner를 컨텍스트로 사용합니다.
제외유형오류:
# 내장 유형 처리
file_path = "해당 없음(내장 또는 C 확장)"
file_name = "해당 사항 없음"
디렉토리 = "해당 사항 없음"
py_name = "해당 사항 없음"
module_name = cls.__모듈__
반환 {
"모듈_이름_또는_메인": 모듈_이름,
"py_name_no_ext": py_name,
"디렉토리": 디렉토리,
"파일_경로": 파일_경로,
}
# 실행하고 결과를 봅니다.
location_info = get_class_location_robust(agent_obj)
print("--- 카테고리 정의 파일 정보 ---")
print(f"파일 이름(.py 이름): {location_info['py_name_no_ext']}")
print(f"디렉터리 경로(패키지): {location_info['directory']}")
print(f"전체 파일 경로: {location_info['file_path']}")
inspect.getfile(type(obj)): 이는 모듈이 고려되는지 여부와 완전히 독립적으로 원본 정의 파일 경로를 직접 가져오는 가장 안정적인 방법입니다.__main__。__module__이는 현재 프로그램에 있는 클래스의 모듈 네임스페이스만 반영하며 프로젝트 구조의 실제 이름이 반드시 반영되는 것은 아닙니다.이 방법은importlib.import_module지정된 모듈을 가져오십시오. 당신이 만난다면ModuleNotFoundError, 현재 로드된 패키지에서 하위 모듈을 가져오려고 시도합니다.
import importlib
importsys
def safe_import(모듈_이름):
시도해 보세요:
# 직접 가져오기를 시도해보세요
return importlib.import_module(모듈_이름)
ModuleNotFoundError 제외:
# 실패하면 알려진 패키지에서 하위 모듈을 가져오려고 시도합니다.
목록(sys.modules.keys())의 패키지에 대해:
pkg.startswith("_")가 아닌 경우:
시도해 보세요:
return importlib.import_module(f"{pkg}.{module_name}")
ModuleNotFoundError 제외:
계속하다
raise # 여전히 찾을 수 없으면 예외를 발생시킵니다.
numpy 가져오기
mod1 = safe_import("random") # 표준 라이브러리이므로 바로 성공 가능
mod2 = safe_import("linalg") # numpy.linalg를 시도합니다.
print(mod2.__name__) # numpy.linalg 출력
sys.modules로드된 모든 모듈을 저장합니다.package.module_name다시 시도하는 방법입니다.파이썬에서는sys.path모듈을 가져오려고 할 때 Python 인터프리터가 순서대로 검색할 모든 디렉터리 경로가 포함된 목록입니다. 실행할 때import some_module, Python이 순서대로 확인합니다.sys.path이름이 지정된 디렉토리를 찾을 때까지 목록의 각 디렉토리some_module파일(예:some_module.py、some_module/__init__.py기다리다).
sys.path목록은 일반적으로 다음 세 부분으로 구성되며 다음 순서로 검색됩니다.
sys.path[0])는 일반적으로 현재 실행 중인 Python 스크립트입니다(예:main.py)은 디렉토리에 있습니다.''는 현재 작업 디렉터리(현재 작업 디렉터리, CWD)를 나타냅니다.PYTHONPATH시스템 환경 변수.sys.path가운데.PYTHONPATH일반적으로 각 프로젝트에서 수동으로 설정할 필요 없이 일반적으로 사용되는 일부 프로젝트 또는 비표준 위치에 있는 라이브러리 디렉토리를 검색 경로에 영구적으로 추가하는 데 사용됩니다.os, sys, json, socket) 설치 디렉토리.pip설치된 타사 패키지(예:fastapi, numpy, pandas) 설치 디렉토리. 가상 환경에서는 일반적으로 해당 환경의lib/site-packages예배 규칙서.위 내용 외에도PYTHONPATH또한 Python 실행 환경과 관련된 여러 환경 변수가 있는데, 이는 인터프리터의 동작과 경로 찾기에 영향을 주지만 영향을 미칩니다.sys.path을 구성하는 주요 변수PYTHONPATH:
| 시스템 변수 | 기능 설명 | sys.path와의 관계 |
|---|---|---|
PYTHONPATH |
모드 검색 경로에 추가할 추가 디렉터리를 정의합니다. | 직접적인 영향sys.path구성. |
PYTHONHOME |
특히 임베디드 시스템의 경우 Python 설치 디렉터리에 대한 대체 경로를 설정하는 데 사용됩니다. | 표준 라이브러리에 간접적으로 영향을 미치며site-packages위치. |
PATH |
운영 체제에서 실행 파일(예:python.exe) 길. |
직접적인 영향을 미치지는 않습니다sys.path, 그러나 어떤 Python 인터프리터가 실행되는지에 영향을 미칩니다. |
VIRTUAL_ENV |
가상 환경에 있는 경우 이 변수는 가상 환경의 루트 디렉터리를 가리킵니다. | 간접적인 영향sys.path, 그것이 보장하는 것처럼site-packages전체 시스템이 아닌 가상 환경에서 비롯됩니다. |
왜냐하면sys.path프로그램이 실행되는 동안 동적으로 수정할 수 있는 일반적인 Python 목록이지만 이러한 수정은 현재 인터프리터 세션 내에서만 적용됩니다.
importsys
수입 OS
# 검색 경로에 상위 디렉터리를 추가합니다(일반적으로 테스트 또는 내부 프로젝트 참조에 사용됨).
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
모듈 섀도잉(또는 이름 섀도잉)은 Python에서 흔히 발생하는 오류 또는 프로그래밍 문제입니다. 이는 가져오거나 사용하려는 내장 모듈 또는 타사 라이브러리의 이름과 충돌하는 코드 파일이나 변수 이름을 실수로 생성한 경우에 발생합니다.
sys.path) 모드를 찾으세요.socket, json, random) 또는 타사 라이브러리와 이름이 같은 파일이나 디렉터리(예:socket.py파일), Python은 로컬 파일을 먼저 로드합니다.그 결과 로컬 파일이 로드되어야 하는 표준 모듈을 "덮거나" "재정의"하여 코드가 표준 모듈 기능(예:socket.AF_UNSPEC)은 로드한 로컬 파일에 이러한 속성이 없기 때문에 실패합니다.
| 표준 모듈 이름 | 그림자를 발생시킨 로컬 파일 이름 | 결과적으로 |
|---|---|---|
socket |
socket.py |
표준을 사용할 수 없습니다socket모듈의 네트워크 상수(예:AF_INET, AI_PASSIVE)。 |
json |
json.py |
표준을 사용할 수 없습니다json모듈식loads또는dumps기능. |
test(프로젝트 이름) |
test.py |
단위 테스트 환경에서는 테스트 프레임워크의 내부 로직과 충돌이 발생할 수 있습니다. |
socket.py이름이 변경됨network_handler.py。import sys; print(sys.path)Python의 검색 경로를 확인하여 표준 라이브러리 디렉터리보다 로컬 파일을 우선적으로 로드하는지 확인하세요.Python 프로그램의 현재 실행을 얻으려면__main__사용할 수 있는 해당 파일이 속한 .py 파일의 이름__main__.__file__또는sys.argv[0]. 하지만 대화형 모드에서는 Jupyter 또는-c실행 시에는 존재하지 않을 수 있으므로 안전한 처리가 필요합니다.
수입 OS
importsys
__main__ 가져오기
def get_main_py_path():
"""main이 속한 .py의 절대 경로를 반환합니다. 찾을 수 없으면 None을 반환합니다."""
# 사례 1: 정상 실행 .py
main_file = getattr(__main__, "__file__", 없음)
main_file인 경우:
os.path.abspath(main_file)를 반환합니다.
# 사례 2: sys.argv[0]의 판단
len(sys.argv) > 0인 경우:
argv0 = sys.argv[0]
argv0이 ("", "-c", "에 없는 경우)"):
후보 = os.path.abspath(argv0)
os.path.exists(후보)인 경우:
복귀 후보
# 사례 3: 대화형 모드, Jupyter, 삽입 등
반환 없음
# 예시
경로 = get_main_py_path()
경로인 경우:
print("기본 경로:", 경로)
print("주 파일명:", os.path.basename(path))
그 외:
print("main.py를 찾을 수 없습니다(대화형 환경에 있거나 아카이브에서 실행되지 않았을 수 있습니다)")
path = get_main_py_path()
filename = os.path.basename(path) if path else None
print(filename)
__main__.__file__가장 신뢰할 수 있는 방법이지만 항상 존재하는 것은 아닙니다.sys.argv[0]백업 방법이지만 값이 백업 방법이 아닌지 확인해야 합니다.-c또는<stdin>。
To get the parameter names and their corresponding values of a function in Python, you can use the `inspect` module, which provides introspection utilities. Specifically, `inspect.signature()` can help you retrieve the names of the parameters, and you can pass the current frame's local variables to get their values.
Here is an example that demonstrates how to get the function name, parameter names, and their values:
```python
import inspect
# Sample function
def my_function(a, b, c=5):
# Get the current frame
frame = inspect.currentframe()
# Get the function name
func_name = frame.f_code.co_name
print(f"Function name: {func_name}")
# Get the parameter names and their values
args, _, _, values = inspect.getargvalues(frame)
# Print parameter names and values
for arg in args:
print(f"Parameter name: {arg}, Value: {values[arg]}")
# Call the function
my_function(1, 2)
```
### Output:
```
Function name: my_function
Parameter name: a, Value: 1
Parameter name: b, Value: 2
Parameter name: c, Value: 5
```
### Explanation:
1. **`inspect.currentframe()`**: Retrieves the current execution frame.
2. **`frame.f_code.co_name`**: Extracts the name of the current function.
3. **`inspect.getargvalues(frame)`**: Gets the argument names and their corresponding values from the frame. This function returns a tuple containing:
- `args`: List of argument names.
- `_`: Placeholder for unused information.
- `values`: Dictionary containing argument names as keys and their values.
This allows you to print both the names of the function's parameters and their values at runtime.
Python에서는 다음을 사용할 수 있습니다.inspect.signature()함수 매개변수 정보를 가져옵니다.
그리고 더 멀리Parameter.annotation이 속성은 각 매개변수에 대한 유형 주석(유형 힌트)을 가져옵니다.
수입 검사
def my_function(a: int, b: str, c: float = 3.14) -> bool:
str(a) == b를 반환합니다.
시그 = 검사.서명(my_function)
이름의 경우 sig.parameters.items()의 매개변수:
print(f"매개변수 이름: {이름}")
print(f"기본값: {param.default}")
print(f"유형 주석: {param.annotation}")
인쇄()
매개변수 이름: a
기본값: <class 'inspect._empty'>
유형 주석: <class 'int'>
매개변수 이름: b
기본값: <class 'inspect._empty'>
유형 주석: <class 'str'>
매개변수 이름: c
기본값: 3.14
유형 주석: <class 'float'>
param.annotation유형 주석을 얻습니다(예:int、str)。inspect._empty。get_type_hints()완전한 유형 힌트 사전을 얻으십시오.이 방법은 전방 참조(문자열로 표시된 유형)를 자동으로 해결합니다.
from typing import get_type_hints
hints = get_type_hints(my_function)
print(hints)
{'a': <class 'int'>, 'b': <class 'str'>, 'c': <class 'float'>, 'return': <class 'bool'>}
inspect.signature()매개변수 순서와 이름을 얻을 수 있습니다.param.annotation각 매개변수의 Type Annotation을 확인할 수 있습니다.get_type_hints()모든 유형 힌트(반환 값 포함)를 한 번에 얻는 것이 더 쉽습니다.Python에서는 객체의__class__속성 또는type()기능,
그것이 속한 카테고리(클래스)를 가져온 다음 카테고리 이름을 가져옵니다.
클래스 동물:
통과
클래스 개(동물):
통과
obj = 개()
#방법 1: __class__.__name__ 사용
print(obj.__class__.__name__) # 출력: 개
#방법 2: type() 사용
print(type(obj).__name__) # 출력: 개
#방법 3: 전체 모듈 및 카테고리 이름 가져오기
print(obj.__class__) # 출력: <class '__main__.Dog'>
print(obj.__class__.__module__) # 출력: __main__
Dog
Dog
<class '__main__.Dog'>
__main__
obj.__class__: 객체의 카테고리 객체를 가져옵니다.obj.__class__.__name__: 카테고리 이름 문자열을 가져옵니다.type(obj)동등하다obj.__class__。__module__: 해당 카테고리가 정의된 모듈의 이름을 알 수 있습니다.완전한 "모듈 + 카테고리 이름"을 동시에 얻으려면 다음과 같이 작성할 수 있습니다.
cls = type(obj)
full_name = f"{cls.__module__}.{cls.__name__}"
print(full_name)
__main__.Dog
type(obj).__name__이는 카테고리 이름을 얻는 가장 간단한 방법입니다.f"{obj.__class__.__module__}.{obj.__class__.__name__}"。다음은 Python을 사용하여 속성이 속한 상속 클래스를 확인하는 샘플 코드입니다.
수입 검사
클래스 BaseClass:
base_attr = "저는 BaseClass의 속성입니다."
클래스 하위 클래스(BaseClass):
sub_attr = "나는 SubClass의 속성입니다"
# 속성이 속한 카테고리를 찾는 함수를 정의합니다.
def find_attribute_owner(cls, attr_name):
for base in Inspection.getmro(cls): # MRO 가져오기(메서드 해결 순서)
base.__dict__에 attr_name이 있는 경우:
반환 기지
반환 없음
# 테스트
sub_obj = 서브클래스()
속성 = sub_obj.__class__.__dict__.items() # 카테고리 수준에서 모든 속성을 가져옵니다.
이름, 속성 값:
소유자 = find_attribute_owner(sub_obj.__class__, 이름)
print(f"'{name}' 속성은 다음 카테고리에 속합니다: {owner.__name__}")
__dict__, 카테고리별로 정의된 속성을 저장합니다.예시의 카테고리에 대한 실행 결과는 다음과 같습니다.
'__module__' 속성은 다음 클래스에 속합니다: SubClass
'sub_attr' 속성은 다음 클래스에 속합니다: SubClass
속성 '__doc__'은(는) 클래스에 속합니다: SubClass
'base_attr' 속성은 BaseClass 클래스에 속합니다.
class MyClass:
def fun1(self):
'''
Fun1 comment
'''
pass
obj = MyClass()
print(obj.fun1.__doc__)
import inspect
class MyClass:
def fun1(self):
'''
Fun1 comment
'''
pass
print(inspect.getdoc(MyClass.fun1))
Python에서는 내장된 기능을 사용할 수 있습니다.warnings컴파일 시간이 아닌 실행 시간에 사용자에게 함수가 더 이상 사용되지 않음을 알리고 새로운 대안을 제안하는 모듈입니다.
수입 경고
def old_function(x, y):
경고.경고(
"old_function() 함수는 더 이상 사용되지 않습니다. 대신 new_function(x, y)를 사용하십시오.",
카테고리=지원 중단 경고,
스택레벨=2
)
x + y를 반환
def new_function(x, y):
x + y를 반환
result = old_function(3, 4)
print(result)
DeprecationWarning: old_function() 함수는 더 이상 사용되지 않습니다. 대신 new_function(x, y)를 사용하십시오.
결과 = old_function(3, 4)
7
warnings.warn()실행 단계 중에 경고가 표시되며 프로그램을 중단하지 않습니다.category=DeprecationWarning사용 중단 경고를 표시하는 데 사용됩니다.stacklevel=2경고 메시지가 함수 내부가 아닌 호출자의 위치를 가리키도록 합니다.python -W error::DeprecationWarning your_script.py
데코레이터를 사용하면 여러 기존 함수가 동일한 지원 중단 프롬프트 논리를 공유할 수 있습니다.
수입 경고
functools 가져오기 랩에서
def는 더 이상 사용되지 않습니다(new_func_name):
def 데코레이터(func):
@wraps(기능)
def 래퍼(*args, **kwargs):
경고.경고(
f"{func.__name__}() 함수는 더 이상 사용되지 않습니다. 대신 {new_func_name}()을 사용하십시오.",
카테고리=지원 중단 경고,
스택레벨=2
)
return func(*args, **kwargs)
반환 포장지
반환 장식자
@deprecated("new_function")
def old_function(x, y):
x + y를 반환
파이썬에서는@staticmethod그리고@classmethod두 데코레이터 모두 클래스를 인스턴스화하지 않고 호출할 수 있는 메서드를 정의할 수 있지만 목적과 동작은 다릅니다.
@staticmethod암시적인 첫 번째 인수를 허용하지 않습니다(없음self또는cls) 방법. 이는 클래스의 네임스페이스에 속하는 일반 함수와 같습니다.@staticmethod。클래스내클래스:
@staticmethod
def static_method(x, y):
x + y를 반환
# 인스턴스를 생성하지 않고도 정적 메서드를 호출할 수 있습니다.
result = MyClass.static_method(5, 10) # 결과: 15
집중하다:@staticmethod카테고리에 접근할 수 없습니다(cls) 또는 인스턴스(self)。
@classmethod승인 카테고리 자체입니다(cls)를 첫 번째 매개변수로 사용합니다. 이를 통해 카테고리 상태에 액세스하고 수정할 수 있습니다.@classmethod。클래스내클래스:
클래스_변수 = 0
def __init__(자체, 값):
self.value = 가치
MyClass.class_variable += 1
@classmethod
def get_class_variable(cls):
cls.class_variable을 반환합니다.
#인스턴스 생성
obj1 = MyClass(10)
obj2 = MyClass(20)
# 통화 카테고리 방법
print(MyClass.get_class_variable()) # 결과: 2
집중하다:@classmethod카테고리 수준 상태에 액세스할 수 있습니다(cls)。
| 특징 | @staticmethod | @classmethod |
|---|---|---|
| 첫 번째 매개변수 | 암시적인 첫 번째 인수 없음 | cls(카테고리 자체) |
| 액세스 인스턴스 | 없음 | 없음 |
| 액세스 카테고리 | 없음 | 가지다 |
| 용법 | 카테고리와 관련되어 있지만 인스턴스나 카테고리가 필요하지 않은 유틸리티 기능 | 카테고리 수준 데이터를 조작하거나 대체 생성자를 제공해야 함 |
Python 자체는 "기본 정적 메서드" 또는 "기본 클래스 메서드", 즉 정적 또는 클래스 메서드가 처음 호출될 때 자동으로 메서드를 실행하는 기능을 제공하지 않습니다. 그러나 지연 로딩 기술을 통해 유사한 동작을 달성할 수 있습니다.
클래스에 정적 변수를 정의하여 초기화된 상태를 추적한 다음 정적 또는 클래스 메서드가 처음 호출될 때 초기화 논리를 실행할 수 있습니다.
클래스내클래스:
초기화 = False # 초기화 여부를 추적하는 정적 변수
@staticmethod
def init_once():
MyClass.initialized가 아닌 경우:
print("초기화 로직 실행...")
MyClass.initialized = True
@classmethod
def class_method(cls):
cls.init_once()
print("클래스 메소드 호출")
@staticmethod
def static_method():
MyClass.init_once()
print("정적 메소드 호출")
# 초기화를 트리거하기 위해 처음으로 카테고리 메소드를 호출합니다.
MyClass.class_method() # 출력: 초기화 논리 실행...클래스 메소드 호출
# 두 번째로 카테고리 메소드를 호출하고 더 이상 초기화를 수행하지 않습니다.
MyClass.class_method() # 출력: 클래스 메소드 호출
# 정적 메서드를 처음 호출하면 이미 초기화되었기 때문에 초기화가 수행되지 않습니다.
MyClass.static_method() # 출력: 정적 메서드 호출
initialized: 해당 카테고리의 초기화 여부를 추적하는 변수입니다. 초기값은False。init_once()방법: 이 메소드는 초기화 로직 실행을 담당하며initialized로 설정True, 반복되는 초기화를 방지합니다.Python에는 기본 제공되는 "기본 정적 메서드" 또는 "기본 클래스 메서드"가 없지만 정적 변수 및 지연 로딩 기술을 사용하면 정적 또는 클래스 메서드가 처음 호출될 때 초기화 논리를 자동으로 실행할 수 있으며 이 논리가 한 번만 실행되도록 할 수 있습니다.
Python에서 스레드는 동시성을 구현하는 데 사용되는 메커니즘입니다. 이를 통해 프로그램은 단일 프로세스(Process) 내에서 여러 작업을 동시에 수행할 수 있습니다. 이는 I/O 집약적인 작업(예: 네트워크 통신, 파일 읽기 및 쓰기)을 수행하는 데 매우 유용하며 프로그램이 외부 작업이 완료될 때까지 기다리는 것을 차단(Blocking)하는 것을 방지할 수 있습니다.
표준 CPython 인터프리터에는 "Global Interpreter Lock"(Global Interpreter Lock, GIL)이 있습니다. GIL은 주어진 시간에 하나의 스레드만 Python 비트코드를 실행할 수 있도록 보장합니다. 이는 다음을 의미합니다.
multiprocessing기준 치수).threadingPython은 표준 함수 라이브러리를 사용합니다.threading실행 스레드를 처리하는 모듈입니다. 스레드 생성에는 두 가지 주요 방법이 있습니다.
이것은 가장 간단하고 가장 일반적인 사용법입니다.
수입 스레딩
수입 시간
def 작업(이름, 지연):
"""스레드에서 실행할 태스크 함수"""
print(f"스레드 {이름}: 시작 중...")
time.sleep(delay) # 시간이 많이 걸리는 I/O 작업을 시뮬레이션합니다.
print(f"스레드 {name}: 작업이 완료되었습니다.")
#실행 스레드 생성
thread1 = threading.Thread(대상=작업, args=("T1", 2))
thread2 = threading.Thread(대상=작업, args=("T2", 4))
# 스레드를 시작합니다
스레드1.시작()
스레드2.시작()
# 모든 스레드가 완료될 때까지 기다립니다(완료될 때까지 메인 스레드를 차단합니다).
thread1.join()
thread2.join()
print("모든 실행 스레드가 완료되었습니다. 메인 프로그램이 종료됩니다.")
threading.Thread범주카테고리에 실행 스레드의 논리를 캡슐화하여 보다 복잡한 시나리오에 적합합니다.
수입 스레딩
수입 시간
클래스 MyThread(threading.Thread):
def __init__(자신, 이름, 지연):
슈퍼().__init__()
self.name = 이름
self.delay = 지연
def 실행(자기):
"""
스레드가 시작되면 run() 메서드가 자동으로 호출됩니다.
여기에서는 스레드가 수행할 작업을 정의합니다.
"""
print(f"스레드 {self.name}: 시작 중...")
시간.수면(self.delay)
print(f"스레드 {self.name}: 작업이 완료되었습니다.")
#스레드 생성 및 시작
thread3 = MyThread("T3", 3)
thread3.시작()
thread3.join()
print("사용자 정의 실행 스레드가 완료되었습니다.")
여러 스레드가 공유 데이터에 액세스하고 수정하면 경쟁 조건이 발생할 수 있습니다. 데이터를 보호하려면 동기화 메커니즘을 사용해야 합니다.
Lock: 잠금은 가장 기본적인 동기화 프리미티브입니다. 스레드가 공유 리소스에 액세스하기 전에 호출됩니다.lock.acquire(), 완료 후 통화lock.release()。RLock(재진입 잠금): 동일한 스레드가 여러 번 잠금을 획득할 수 있도록 허용합니다.Semaphore(로그): 동시에 리소스에 접근할 수 있는 스레드 수를 제한하는 데 사용됩니다.수입 스레딩
# 공유 리소스
카운터 = 0
# 잠금 생성
잠금 = 스레딩.Lock()
def increment_counter():
글로벌 카운터
# 동시에 단 하나의 스레드만이 이 블록을 실행할 수 있도록 잠금을 획득합니다.
잠금.획득()
시도해 보세요:
# 공모전 섹션
현재_값 = 카운터
time.sleep(0.001) # 전환 시뮬레이션
카운터 = 현재_값 + 1
마지막으로:
# 잠금 해제
잠금.해제()
스레드 = []
범위(100)에 있는 i의 경우:
t = 스레딩.스레드(대상=increment_counter)
스레드.추가(t)
t.시작()
스레드의 t에 대해:
t.join()
print(f"최종 카운터 값: {counter}") # 잠금이 없으면 이 값은 100이 아닐 수 있습니다.
파이썬threading모듈은 실행 스레드를 생성하고 관리하는 기능을 제공하지만 운영 체제 제한 및 설계 철학으로 인해 Python은 외부 실행 스레드를 중지(Kill)하는 안전하고 직접적이며 강제적인 방법을 제공하지 않습니다. 강제로 중지하면 리소스 누출이나 데이터 손상이 발생할 수 있습니다.
따라서 실행 스레드를 중지하려면 **협력 메커니즘****을 통해 이루어져야 합니다. 즉, 실행 스레드가 스스로 중지 플래그를 확인하고 정상적으로 종료되도록 해야 합니다.
이는 가장 안전하고 권장되는 스레드 중지 방법입니다. 스레드가 작업 실행 루프에서 외부 변수(플래그)를 주기적으로 확인해야 합니다.
수입 스레딩
수입 시간
# 공유 중지 플래그
stop_flag = 스레딩.이벤트()
def monitor_task(이름, 지연):
"""
정지 플래그를 주기적으로 확인하는 태스크 기능
"""
print(f"스레드 {이름}: 시작 중...")
나는 = 0
while not stop_flag.is_set(): # 플래그가 설정되어 있는지 확인합니다.
나는 += 1
print(f"스레드 {이름}: 실행 단계 {i}")
# 시간이 많이 걸리는 작업을 시뮬레이션하고 정기적으로 확인합니다.
시간.수면(지연)
# 여기에서는 무한 루프가 발생하지 않도록 실행 횟수 제한을 설정할 수 있습니다.
내가 >= 5인 경우:
휴식
print(f"실행 스레드 {name}: 중지 신호를 받았거나 작업이 종료되어 정상적으로 종료되었습니다.")
# --- 메인 프로그램 제어 블록 ---
#실행 스레드 생성
Worker_thread = threading.Thread(target=monitored_task, args=("Worker-1", 1))
# 스레드를 시작합니다
작업자_스레드.시작()
print("\n메인 프로그램: 실행 스레드가 시작되었습니다. 3초 동안 기다리십시오...\n")
time.sleep(3) # 잠시 동안 스레드를 실행하도록 둡니다.
# 정지 신호 보내기
print("\n메인 프로그램: 정지 플래그 설정...\n")
stop_flag.set() # 이벤트를 설정하고 is_set()가 True를 반환하도록 합니다.
# 스레드가 정상적으로 완료되고 종료될 때까지 기다립니다(보통 빠르게).
작업자_스레드.조인()
print("\n메인 프로그램: 스레드가 안전하게 중지되고 조인되었습니다. 프로그램이 종료되었습니다.")
threading.Event(): 간단한 동기화 프리미티브입니다. 내부적으로 Bollinger 플래그를 유지합니다.stop_flag.is_set(): 플래그가 True인지(즉, 정지 신호가 발행되는지) 확인합니다.stop_flag.set(): 정지 신호를 보내려면 플래그를 True로 설정합니다.while not stop_flag.is_set():: 이것은 스레드의 주요 제어 구조입니다. 정지 신호가 수신되지 않는 한 루프는 계속 실행됩니다.worker_thread.join(): 실행을 계속하기 전에 기본 프로그램이 작업 스레드가 완료(정상적으로 종료)될 때까지 기다리는지 확인하세요. 이는 절차를 깔끔하게 마무리하는 중요한 단계입니다.`_thread.stop()`을 사용하거나 예외를 발생시키는 등 강제로 중지하는 몇 가지 실험적이거나 안전하지 않은 방법이 있지만 이러한 방법으로 인해 다음이 발생할 수 있습니다.
따라서 Python에서는 항상 조정된 플래그 지정 메커니즘을 사용하여 스레드를 중지해야 합니다.
이는 다중 스레드 환경에서 가장 권장되는 접근 방식입니다. 모든 스레드가 동일한 개체를 가져오는 대신 각 스레드는 개체의 독립적인 복사본을 갖습니다. Python에서는 다음을 사용할 수 있습니다.threading.local()달성하기 위해.
수입 스레딩
# 객체를 저장할 스레드 영역을 만듭니다.
thread_data = threading.local()
def get_service():
# 현재 스레드에 자체 서비스가 없으면 새로 만듭니다.
hasattr(thread_data, 'service')가 아닌 경우:
print(f"{threading.current_thread().name} 스레드에 대한 새 연결을 생성합니다")
thread_data.service = create_new_connection()
thread_data.service를 반환합니다.
데프 작업():
서비스 = get_service()
# 작업 수행...
객체가 동일해야 하는 경우(예: 동일한 파일에 쓰거나 동일한 전역 카운터에서 작동) 다음을 사용해야 합니다.Lock. 이렇게 하면 경쟁 조건을 방지하면서 동시에 하나의 스레드만 개체에 액세스할 수 있습니다.
잠금 = 스레딩.Lock()
def safe_task():
자물쇠 포함:
# 이 블록 내에서 다른 스레드는 기다려야 합니다.
shared_object.do_something()
---
여러 스레드에서 발생하는 잠금 경합이나 충돌의 위험을 피하려면 고려해야 할 두 가지 주요 대안이 있습니다.
이는 현재 Python에서 가장 널리 사용되는 접근 방식입니다(예: FastAPI의 핵심 원칙). 단일 스레드 내에서 실행되며 작업을 전환하여 I/O(예: API 요청, 데이터베이스 쿼리)를 기다립니다.
비동기 가져오기
비동기 def fetch_api(url):
# aiohttp와 같은 비동기 라이브러리를 사용합니다.
응답 = call_api(url) 대기
응답 반환
비동기 정의 메인():
# 동시에 여러 작업을 실행하지만 단일 스레드 내에서 전환합니다.
결과 = asyncio.gather(fetch_api("url1"), fetch_api("url2"))를 기다립니다.
Python의 실행 스레드는 GIL(Global Interpreter Lock)에 의해 제한되며 작업을 실제로 병렬화할 수 없습니다.multiprocessing여러 개의 독립적인 Python 인터프리터 인스턴스가 열립니다.
다중 처리 가져오기 프로세스에서
def 작업(이름):
print(f"{name} 프로세스가 실행 중입니다.")
__name__ == "__main__"인 경우:
p = 프로세스(대상=작업, args=('A',))
p.start()
p.join()
작업을 완전히 분리하려면 Celery 또는 Redis Queue를 사용할 수 있습니다. 작업을 대기열에 넣고 백엔드 작업자(여러 프로세스 또는 다중 시스템일 수 있음)가 이를 선택하고 실행하도록 합니다.
---| 계획 | 해결책 | 적용 가능한 상황 |
|---|---|---|
| Thread-Local | 각 스레드는 복사본을 얻습니다. | API 서비스, 데이터베이스 연결 |
| Asyncio | 단일 스레드 전환(비동기) | 높은 동시 네트워크 요청(권장) |
| Multiprocessing | 독립 기억 공간 | 공유 충돌을 완전히 방지하는 CPU 컴퓨팅 |
TLS(스레드 로컬 저장소)를 사용하는 경우 목적은 "스레드로부터 안전하지 않은" 개체(예: API 서비스, 데이터베이스 연결)를 보호하는 것입니다. 그러나 스레드 간에 데이터를 교환해야 하는 경우(예: 스레드 A에서 다운로드한 결과를 스레드 B에서 처리해야 하는 경우) 특별한 "통신 채널"을 설정해야 합니다.
파이썬queue.Queue스레드로부터 안전합니다. 이는 스레드 간에 정보를 전송하는 가장 표준적이고 안전한 방법입니다. 이미 내부적으로 모든 잠금 로직을 처리했습니다.
수입 스레딩
가져오기 대기열
# 모든 실행 스레드가 접근할 수 있는 전역 큐를 생성합니다.
task_queue = 대기열.큐()
데프 생산자():
# 데이터를 생성하고 대기열에 넣습니다.
데이터 = {"video_id": "abc", "status": "보류 중"}
task_queue.put(데이터)
데프 소비자():
# 큐에서 데이터를 가져옵니다
데이터 = task_queue.get()
# 데이터 처리...
task_queue.task_done()
큰 목록이나 사전을 공유해야 하는 경우 일반 전역 변수를 사용할 수 있지만 일치하는 항목으로 액세스해야 합니다.threading.Lock。
공유_결과 = []
results_lock = 스레딩.잠금()
데프 작업():
result = "일부 작업 결과"
#공유 리소스에 액세스하기 전에 잠금
results_lock 사용:
shared_results.append(결과)
# with 블록을 떠난 후 자동으로 잠금 해제
때로는 "데이터"가 아닌 "상태"를 공유하고 싶을 때가 있습니다(예: API가 초기화되었음을 다른 스레드에 알리기).
api_ready = 스레딩.이벤트()
def 초기화():
#초기화 수행
api_ready.set() # 신호 보내기
데프 작업자():
api_ready.wait() # 초기화 프로그램이 set()을 호출할 때까지 신호를 기다립니다.
print("작업 시작")
| 콘텐츠 유형 | 저장 위치 | 경영 스타일 |
|---|---|---|
| 도구 개체(API, DB 연결) | 스레드-로컬(지역) | 각각에는 충돌을 방지하기 위한 사본이 있습니다. |
| 미션정보(ID, 매개변수) | 대기열(전역) | 스레드로부터 안전한 대기열 전달을 사용합니다. |
| 계산 결과(통계) | 전역 목록/사전(전역) | 일치해야 함threading.Lock。 |
간단히 말하면: **"개인 도구(연결)를 직접 가져오고 대기열(큐/잠금)에서 공개 정보(데이터)를 가져옵니다."**
멀티 스레드 환경에서는 여러 스레드가 동일한 전역 변수나 공유 리소스(예: 파일, 데이터베이스 연결, 전역 목록)를 동시에 수정하려고 하면 오류가 발생합니다.경쟁 조건, 데이터 혼란을 초래합니다.threading.Lock한 번에 하나의 스레드만 보호된 코드 블록에 들어갈 수 있도록 보장하는 동기화 기본 요소입니다.
가장 안전하고 권장되는 방법은 일치하는 것입니다.with서술형 문장을 사용하세요. 이렇게 하면 블록 내에서 예외가 발생하더라도 교착 상태를 방지하기 위해 잠금이 올바르게 해제됩니다.
수입 스레딩
# 1. 잠금 객체 생성
my_lock = 스레딩.잠금()
공유 카운터 = 0
def increment_task():
전역 공유_카운터
# 2. acquire() 및 release()를 자동으로 관리하려면 with를 사용하세요.
my_lock 사용:
# 이 블록의 코드는 한 번에 하나의 스레드에서만 실행될 수 있습니다.
온도 = 공유_카운터
온도 += 1
shared_counter = 임시
# 다중 스레드 테스트 시작
스레드 = [threading.Thread(target=increment_task) for _ in range(100)]
스레드의 t에 대해: t.start()
스레드의 t에 대해: t.join()
print(f"최종 개수: {shared_counter}")
권장되지는 않지만 때로는 더 미세한 제어가 필요할 수 있습니다. 수동으로 전화해야 합니다.acquire()자물쇠를 획득하고finally블록에 전화release()。
잠금 = 스레딩.Lock()
def manual_task():
lock.acquire() # 잠금을 획득합니다. 잠금이 이미 점유된 경우 여기에서 차단(대기)됩니다.
시도해 보세요:
# 작업 실행
통과
마지막으로:
lock.release() # 해제되어야 합니다. 그렇지 않으면 다른 스레드가 절대 실행될 수 없습니다.
threading.Lock재진입이 아닙니다. 이는 동일한 스레드가 이미 잠금을 보유하고 있을 때 동일한 잠금을 다시 요청하면 자체적으로 "잠김"(교착 상태)이 발생함을 의미합니다.
threading.RLock()(재진입 잠금).Google API Service물체.잠금을 과도하게 사용하면 여러 스레드가 "실행 대기" 상태가 되므로 프로그램 성능이 저하됩니다. 가능하다면 우선적으로 사용하세요.queue.Queue아니면 우리가 이전에 논의한 것Thread-Local Storage, 이러한 방법은 일반적으로 빈번한 잠금보다 더 효율적이고 오류가 덜 발생합니다.
파이썬에서는async def그리고await실현된다비동기 프로그래밍핵심 구문. I/O 작업(예: 네트워크 요청, 파일 읽기)을 기다리는 동안 프로그램이 멈추는 것을 방지하고 대신 다른 작업을 처리하여 성능을 크게 향상시킬 수 있습니다.
함수 정의 앞에 다음을 추가하면async, 함수는 다음과 같습니다.코루틴 함수. 호출하면 콘텐츠가 즉시 실행되지 않지만 "코루틴 개체"가 반환됩니다.
비동기 def fetch_data():
print("데이터 가져오기 시작...")
# 시간이 많이 걸리는 작업을 시뮬레이션합니다.
{"데이터": "성공"}을 반환합니다.
# 직접 호출은 코루틴 객체만 가져오고 인쇄는 실행하지 않습니다.
결과 = fetch_data()
print(result) # 출력: <코루틴 객체 fetch_data at ...>
await오직 될 수 있다async def내부용. 그 기능은 "현재 코루틴을 일시적으로 중단하고 후속 작업이 완료될 때까지 기다린 후 반환 값을 얻는 것"입니다. 기다리는 동안 시스템은 다른 비동기 작업을 수행할 수 있습니다.
비동기 가져오기
비동기 정의 메인():
# 코루틴을 실행하고 결과를 얻으려면 wait를 사용하세요.
데이터 = fetch_data()를 기다립니다
print(f"캡처 결과: {data}")
# 비동기 프로그램에 대한 항목을 시작합니다.
asyncio.run(메인())
| 문법 | 기능 설명 | 주의할 점 |
|---|---|---|
| async def | 비동기 함수 선언 | 반환되는 것은 실행 결과가 아닌 코루틴 객체입니다. |
| await | 비동기 작업이 완료될 때까지 기다립니다. | 비동기 함수 내에서만 작성할 수 있습니다. |
| asyncio.run() | 가장 바깥쪽 비동기 항목 시작 | 프로그램은 일반적으로 한 번만 호출하면 됩니다. |
await, 당신은 얻을 것이다coroutine객체의 속성(예:result.text)는 다음과 같은 경우에 분사됩니다.AttributeError。SyntaxError. 외부 기능이 다음과 같은지 확인해야 합니다.async그루밍.async함수에 사용됨time.sleep()전체 이벤트 루프를 차단합니다. 대신 사용해 주세요await asyncio.sleep()。당신이 요리를 하고 있다고 상상해보세요:
await) 동시에 야채를 자르러 갈 때 물 끓는 소리(이벤트 알림)가 이를 처리하기 위해 다시 전화합니다.loop.run_until_complete()예asyncio모듈의 하위 수준 메서드는 코루틴이 완료될 때까지 실행하고 결과를 반환하는 데 사용됩니다. Python 3.7 이후에는 공식적으로 사용을 권장하지만asyncio.run(), 그러나 일부 특정 상황(예: 이벤트 루프를 재사용해야 하거나 시작 논리를 사용자 정의해야 하는 경우)에서는 여전히 이 방법을 사용해야 합니다.
사용run_until_complete먼저 이벤트 루프 객체를 얻거나 생성한 다음 여기에 코루틴을 전달해야 합니다.
비동기 가져오기
비동기 def my_task():
asyncio.sleep을 기다립니다(1)
"작업 완료"를 반환합니다.
# 1. 이벤트 루프 가져오기
루프 = asyncio.get_event_loop()
# 2. 완료될 때까지 코루틴을 실행하고 반환 값을 직접 가져옵니다.
결과 = loop.run_until_complete(my_task())
print(result) #Output: 작업 완료
둘 다 반환 값을 얻을 수 있지만 수명 주기를 다르게 관리합니다.
| 특성 | asyncio.run() (권장) | loop.run_until_complete() |
|---|---|---|
| 자동화 정도 | 높은. 자동으로 루프를 생성하고 닫고 작업을 정리합니다. | 낮은. 루프의 수명주기는 수동으로 관리해야 합니다. |
| 재사용성 | 낮은. 호출할 때마다 새로운 루프가 생성됩니다. | 높은. 동일한 루프에서 여러 작업을 실행할 수 있습니다. |
| 사용 제한 | 이미 실행 중인 루프 내에서는 사용할 수 없습니다. | 더 유연하며 레거시 코드 또는 테스트 환경에서 자주 사용됩니다. |
이미 실행 중인 스크립트에서 코루틴이 실행되고 값을 얻었는지 확인하려는 경우 다음 방법을 사용할 수 있습니다.
비동기 가져오기
비동기 def 추가(a, b):
a + b를 반환
루프 = asyncio.new_event_loop()
asyncio.set_event_loop(루프)
시도해 보세요:
# 첫 번째 작업을 실행
val1 = loop.run_until_complete(추가(10, 20))
#두번째 작업 실행
val2 = loop.run_until_complete(추가(val1, 5))
print(f"최종 결과: {val2}")
마지막으로:
# 수동으로 닫아야 함
루프.닫기()
여러 코루틴을 병렬로 실행하고 반환 값을 균일하게 검색하려면 다음을 일치시켜야 합니다.asyncio.gather:
비동기 def 작업(id):
f"결과 {id}"를 반환합니다.
루프 = asyncio.get_event_loop()
# 수집은 여러 코루틴을 하나의 작업으로 래핑하고, run_until_complete는 모두 완료될 때까지 기다립니다.
결과 = loop.run_until_complete(asyncio.gather(task(1), task(2), task(3)))
print(results) #출력: ['결과 1', '결과 2', '결과 3']
async def함수 내에서 호출run_until_complete, 뿜어져 나올 것이다This event loop is already running. 항상 비동기 함수 내에서 사용하세요.await。loop.close()그렇지 않으면 프로그램이 정상적으로 종료되지 않거나 경고가 생성될 수 있습니다.run_until_complete코루틴을 반환합니다return코루틴에서 포착되지 않은 예외가 발생하면 해당 예외는 호출 측으로 전달됩니다.asyncio.run()Python 3.7부터 도입된 고급 API입니다. 비동기 프로그램을 시작하는 데 가장 권장되는 방법입니다. 자동으로 처리됩니다이벤트 루프를 설정하고, 코루틴을 실행하고, 완료 후 루프를 닫습니다.. 가장 중요한 것은 코루틴으로 직접 다시 전달된다는 것입니다.return값.
당신은 단지async def전달된 함수 호출은asyncio.run(), 일반 동기 함수와 같은 결과를 반환합니다.
비동기 가져오기
비동기 def 계산_점수(이름):
print(f"{name}의 점수를 계산하는 중...")
wait asyncio.sleep(1) # 시간이 많이 걸리는 작업을 시뮬레이션합니다.
95를 반환
# 반환 결과를 직접 가져옵니다.
final_score = asyncio.run(calculate_score("장샤오밍"))
print(f"최종 점수: {final_score}") # 출력: 95
일반적으로 우리는main()진입점으로 기능하고 내부의 모든 하위 작업 결과를 얻습니다.asyncio.run(main())통합 출력.
비동기 def task_a():
"사과"를 반환
비동기 def task_b():
"바나나"를 반환
비동기 정의 메인():
# 동시에 실행하려면 메인에서 수집을 사용하세요.
결과 = asyncio.gather(task_a(), task_b())를 기다립니다.
결과 반환 # 목록 반환
# asyncio.run을 통해 main의 반환 값을 가져옵니다.
all_fruits = asyncio.run(main())
print(all_fruits) # 출력: ['apple', 'banana']
| 규칙 항목 | 설명하다 |
|---|---|
| 단일 입구 | 연속 실행에서는 일반적으로 한 번만 호출됩니다.asyncio.run()。 |
| 자동 청소 | 나머지 작업을 모두 자동으로 취소하고 스레드 풀을 닫으므로 매우 안전합니다. |
| 중첩 한도 | 할 수 없다이미async def함수 내부 호출asyncio.run()。 |
다른 비동기 함수의 결과를 얻으려는 비동기 함수 내부에 있는 경우 다음을 사용하세요.await, 대신asyncio.run()。
# 오류 시연
비동기 def sub_task():
10을 반환
비동기 정의 메인():
# 여기서 오류가 발생합니다: RuntimeError: asyncio.run()은 실행 중인 이벤트 루프에서 호출할 수 없습니다.
res = asyncio.run(sub_task())
# 올바른 교정
비동기 정의 메인():
res = wait sub_task() # 비동기 환경에서는 wait를 사용하세요
asyncio.run()프로그램의 시작 버튼으로if __name__ == "__main__":블록에서.asyncio.run()예외가 직접 발생합니다. 다음을 권장합니다.run외부 레이어 플러스try...except。asyncio.run()그대로 제거할 수 있습니다.NumPy(Numerical Python)은 Python에서 가장 중요한 과학 컴퓨팅 라이브러리입니다. 효율적인 다차원 배열 객체를 제공합니다.ndarray, 그리고 이러한 배열을 조작하기 위한 대규모 수학 함수 라이브러리. 이는 데이터 과학, 기계 학습(예: Pandas, Scikit-learn, TensorFlow) 및 기타 분야의 기본 기둥입니다.
for원.numpy를 np로 가져오기
# 1차원 배열과 2차원 배열을 만듭니다.
arr1 = np.array([1, 2, 3])
arr2 = np.array([[1, 2], [3, 4]])
# 특정 배열을 빠르게 생성
zeros = np.zeros((3, 3)) # 모두 0인 3x3 행렬
ones = np.ones((2, 4)) # 모두 1인 2x4 행렬
eye = np.eye(3) # 3x3 단위 행렬
range_arr = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
| 기능 | 코드 예시 | 설명하다 |
|---|---|---|
| 형태체크 | arr.shape |
각 차원의 크기를 반환합니다(예: (3, 2)). |
| 모양을 바꾸다 | arr.reshape(1, 6) |
데이터를 변경하지 않고 차원을 변경합니다. |
| 행렬 곱셈 | np.dot(a, b)또는a @ b |
선형 대수학에서 행렬 곱셈을 수행합니다. |
| 통계 함수 | np.mean(), np.std() |
평균, 표준편차, 최대값, 최소값을 계산합니다. |
NumPy의 슬라이싱 구문은 Python List와 유사하지만 더 강력하고 다차원 동시 슬라이싱을 지원합니다.
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 두 번째 열(인덱스 1)을 가져옵니다.
print(arr[1, :]) # [4, 5, 6]
# 오른쪽 하단 모서리에 있는 2x2 하위 행렬을 가져옵니다.
print(arr[1:, 1:]) # [[5, 6], [8, 9]]
pip install numpy또는conda install numpy。import numpy as np
print(np.__version__)
앞서 언급했듯이,NumbaNumPy의 배열 구조를 완벽하게 인식하고 복잡한 NumPy 연산을 기계어 코드로 컴파일하여 네이티브 C 언어에 가까운 실행 한계에 도달할 수 있습니다.
Numba대용량 데이터를 처리하는 Python 코드를 가속화하도록 특별히 설계된 오픈 소스 JIT(Just-In-Time) 컴파일러입니다. C, C++ 또는 Fortran에 필적하는 실행 속도로 Python 함수를 기계어 코드로 변환할 수 있으며 특히 다음과 같은 경우에 적합합니다.NumPy배열 작업.
Numba를 사용하는 가장 쉬운 방법은 다음을 추가하는 것입니다.@jit또는@njit데코레이터.
numba import njit에서
numpy를 np로 가져오기
# @njit는 "nopython" 모드를 나타내며, Python 파서에 들어가지 않도록 하며 가장 빠릅니다.
@njit
def fast_function(n):
합계=0
범위(n)에 있는 i의 경우:
합계 += 나
반품 총액
# 첫 번째 호출은 컴파일되고, 두 번째 호출은 기계어 코드를 직접 실행합니다.
인쇄(fast_function(10000000))
| 모델 | 데코레이터 | 설명하다 |
|---|---|---|
| 노파이썬 모드 | @njit |
추천합니다.Python 인터프리터와 완전히 분리되어 기계어 코드로 직접 컴파일됩니다. 프로그램 코드에 컴파일할 수 없는 부분이 포함되어 있으면 오류가 보고됩니다. |
| 객체 모드 | @jit |
컴파일할 수 없으면 실행을 위해 Python 파서로 대체됩니다. 성능 향상은 일반적으로 제한됩니다. |
CPU의 멀티 코어 기능을 활용하려면 간단히 전원을 켜십시오.parallel=True그리고 사용prange。
numba import njit, prange에서
@njit(병렬=참)
def 병렬_합(A):
초 = 0
# prange는 자동으로 루프를 다른 CPU 코어에 할당합니다.
i의 경우 prange(A.shape[0]):
s += A[i]
반환하다
pip install numba또는conda install numba。llvmlite도서관).import numba
print(numba.__version__)
dict、list또는 개체를 사용자 정의할 때 성능이 저하됩니다.Pandas는 표 형식 데이터 또는 시계열 데이터와 같은 구조화된 데이터를 처리하도록 설계된 Python 기반 데이터 분석 및 조작 도구입니다.
팬더를 PD로 가져오기
# 데이터프레임 생성
data = {'이름': ['앨리스', '밥', '찰리'],
'나이': [25, 30, 35],
'도시': ['타이베이', '타이중', '가오슝']}
df = pd.DataFrame(데이터)
# 데이터 보기
인쇄(df)
# 28세보다 오래된 정보를 필터링합니다.
filtered_df = df[df['나이'] > 28]
인쇄(filtered_df)
Pandas는 효율적이고 유연하며 직관적인 작업 방법을 제공하며 이는 특히 데이터 분석 및 처리에 적합합니다. 이는 데이터 과학 및 기계 학습에 없어서는 안될 도구 중 하나입니다.
Pandas는 강력한 데이터 분석 도구이며 초보자와 고급 사용자 모두 사용하기 쉬운 디자인과 광범위한 기능의 이점을 누릴 수 있습니다.
먼저 설치해야합니다googletrans전부. 명령줄에 다음 명령을 입력합니다.
pip install googletrans==4.0.0-rc1
참고: 설치 시 버전을 확인하세요.4.0.0-rc1, 이전 버전은 더 이상 작동하지 않을 수 있습니다.
다음은 영어를 중국어 번체로 번역하는 예입니다.
googletrans 가져오기 번역기에서
#Translator 개체 초기화
번역가 = 번역가()
# 텍스트 번역
text = "안녕하세요?"
결과 = Translator.translate(text, src="en", dest="zh-tw")
# 번역 결과 출력
print("원본 텍스트:", text)
print("번역:", result.text)
여러 언어를 번역할 수 있습니다. 공통 언어 코드는 다음과 같습니다.
enzh-twzh-cnjakofrdeGoogletrans는 비공식 Google 번역 API이며 Google 측의 변경으로 인해 작동이 중단될 수 있습니다. 번역 기능이 작동하지 않는 경우 Google 공식 Cloud Translation 등 다른 번역 API를 사용해 보세요. API.
DeepL은 정확도가 높은 번역 서비스를 제공하지만 개발자 API를 사용하려면 API 키가 필요합니다.
Microsoft에서 제공하는 번역 도구는 다국어 번역을 지원하지만 Azure API 키 설정을 사용해야 합니다.
Amazon Web Services(AWS)에서 제공하는 번역 서비스는 다국어 텍스트를 효율적으로 번역하며 AWS에서 제공하는 API 키를 통해 액세스해야 합니다.
LibreTranslate는 자체 서버를 설정할 수 있고 API 키가 필요하지 않은 오픈 소스 번역 도구입니다. 일부 타사 공개 서버는 API 키 없이도 사용할 수 있는 옵션을 제공합니다.
TextBlob은 Google 번역 기능이 내장된 자연어 처리 기반 도구입니다. 그러나 이전 버전에는 API 키가 필요하지 않으며 버전 지원에 주의가 필요할 수 있습니다.
MyMemory는 메모리 기반 번역을 제공합니다. 일부 기능에는 API 키가 필요하지 않지만 고급 사용에는 애플리케이션이 필요할 수 있습니다.
Googletrans의 경쟁사 중에서 LibreTranslate 및 일부 버전의 TextBlob은 API 키가 필요하지 않은 옵션을 제공합니다. 완전 무료이고 추가 설정이 필요하지 않은 도구가 필요한 경우 다음 옵션을 고려하십시오.
OpenCC(Open Chinese Convert)는 중국어 간체를 중국어 번체로 변환하는 데 전념하는 오픈 소스 프로젝트입니다. 단순한 단어 대 단어 변환이 아니라, 더 중요한 것은어휘 수준지역별(중국 본토, 대만, 홍콩) 단어 사용 습관의 전환 및 차이.
Python에서 가장 일반적으로 사용되는 패키징 라이브러리는 다음과 같습니다.opencc-python-reimplemented。
# 설치 지침
pip는 opencc-python-reimplemented를 설치합니다.
# 기본 코드 예시
opencc에서 OpenCC 가져오기
# 초기화, s2t는 Simplified to Traditional(Simplified to Traditional)을 나타냅니다.
cc = 오픈CC('s2t')
text = "인공지능이 세상을 바꿨습니다"
결과 = cc.convert(텍스트)
print(result) #Output: 인공지능이 세상을 바꾸었습니다.
| 스키마 이름 | 설명하다 | 적용 가능한 상황 |
|---|---|---|
| s2t | 중국어 간체에서 중국어 번체로 | 표준 문자를 단순 문자에서 일반 문자로 변환합니다. |
| t2s | 중국어 번체에서 중국어 간체로 | 표준 문자는 번체에서 간체로 변환됩니다. |
| s2twp | 중국어 간체에서 대만어 중국어 번체(단어 포함) | 대만에서 가장 일반적으로 사용됩니다."소프트웨어"를 "소프트웨어"로 변환합니다. |
| tw2s | 대만 중국어 번체에서 중국어 간체로 | 대만어 관용어를 중국 본토 중국어 간체로 변환합니다. |
| s2hk | 홍콩 번체로 단순화됨 | 홍콩의 단어 사용 습관에 따릅니다(예: "里"를 "里"로 변경). |
프로그램을 작성하고 싶지 않다면 OpenCC를 터미널에서 직접 작동할 수도 있습니다.
# 간체에서 대만어 번체 모드를 사용하여 input.txt를 output.txt로 변환합니다.
opencc -i input.txt -o 출력.txt -c s2twp.json
reimplemented버전..json파일 정의, OpenCC 설치 디렉터리로 이동하여 이러한 사전이 어떻게 작동하는지 확인할 수 있습니다.다음 예에서는 Python을 사용하여 한자의 모든 음성 표기법을 쿼리하는 방법을 보여줍니다. 우리는 사용pypinyin한자의 병음을 구하고 병음부터 발음기호까지의 대응표를 커스터마이즈하는 키트입니다.
pip install pypinyin
다음은 HTML 결과를 쿼리하고 생성하기 위한 음성 대응 테이블과 프로그램 논리를 포함하는 Python 코드입니다.
피핀인에서 병음 가져오기, 스타일
jinja2 가져오기 템플릿에서
# 병음에서 주음까지의 간단한 대응표
pinyin_to_zhuyin = {
"a": "ㄚ", "ai": "ㄞ", "an": "ㄢ", "ang": "ㄤ", "ao": "ㄠ",
"ba": "ㄅㄚ", "bai": "ㄅㄞ", "ban": "ㄅㄢ", "bang": "ㄅㄤ", "bao": "ㄅㄠ",
# 일부 서신을 생략하고 직접 개선해야 함
"hao": "ㄏㄠ", "hao": "ㄏㄠ", "hao": "ㄏㄠ Should", "hào": "ㄏㄠˋ"
}
# 한자의 모든 병음을 쿼리하여 병음으로 변환
def get_zhuyin(char):
pinyins = pinyin(char, 스타일=Style.NORMAL, heteronym=True)
Unique_pinyins = 설정(병음[0])
zhuyins = {p: pinyin_to_zhuyin.get(p, p) for p in Unique_pinyins} # 병음을 주음으로 변환
반환 목록(zhuyins.values())
# 쿼리 문자
Chinese_char = 'good' # 다른 문자로 대체 가능
zhuyin_results = get_zhuyin(chinese_char)
pinyin_to_zhuyin병음을 음성 기호에 매핑하는 사전입니다. 이 대응표는 자체적으로 확장되어야 합니다.heteronym=True다중 음성 문자의 모든 발음이 표시되는지 확인하십시오.수입 OS
# 파일인지 확인
os.path.isfile("example.txt")인 경우:
print("파일이 존재합니다.")
# 폴더인지 확인
os.path.isdir("my_folder")인 경우:
print("폴더가 존재합니다.")
# 파일이나 폴더가 존재하는지 확인
os.path.exists("경로/to/check")인 경우:
print("경로가 존재합니다")
pathlib import 경로에서
경로 = 경로("example.txt")
path.exists()인 경우:
print("경로가 존재합니다")
path.is_file()인 경우:
print("파일입니다")
path.is_dir()인 경우:
print("폴더입니다.")
Python에서 파일 복사, 이동, 이름 바꾸기 및 삭제를 처리하는 가장 표준적이고 강력한 모듈은 다음과 같습니다.shutil(상위 수준 작업의 경우) 및os(기본 경로 작업용)
복사 작업에는 메타데이터를 보존해야 하는지 여부(예: 생성 시간, 권한)에 따라 다른 기능이 있습니다.
수입 차단
# 단일 파일 복사
Shutil.copy2('source.txt', 'destination.txt')
# 전체 폴더를 복사합니다(대상 폴더가 존재하지 않아야 함).
Shutil.copytree('my_folder', 'backup_folder')
이동 및 이름 바꾸기의 기본 논리는 매우 유사합니다. 사용shutil.move여러 디스크에서 실행될 수 있지만os.rename동일한 디스크의 이름을 바꾸는 데 자주 사용됩니다.
| 기능 | 일반적인 명령 | 설명하다 |
|---|---|---|
| 파일 또는 디렉터리 이동 | shutil.move(src, dst) |
파일이나 전체 디렉터리를 새로운 경로로 이동하여 파티션 간을 지원합니다. |
| 파일 이름 바꾸기 | os.rename(old, new) |
파일 또는 디렉터리 이름을 변경합니다. |
수입 차단
수입 OS
# 파일 이동
Shutil.move('test.txt', 'archive/test.txt')
# 이름 바꾸기
os.rename('old_name.txt', 'new_name.txt')
삭제 작업은 주의해서 사용해야 합니다. 이러한 명령은 일반적으로 휴지통을 거치지 않고 직접 영구적으로 제거하기 때문입니다.
# 단일 파일 삭제
os.path.exists('temp.txt')인 경우:
os.remove('temp.txt')
# 폴더 전체를 강제로 삭제
Shutil.rmtree('old_data_folder')
복사 또는 이동을 수행하기 전에 프로그램 충돌을 방지하기 위해 경로가 존재하는지 확인하십시오.
os.path.join()또는pathlib프로그램이 Windows(백슬래시)와 Linux(슬래시) 간에 작동하도록 경로를 결합하는 모듈입니다.try...except팩.shutil.copy그리고shutil.move동일한 이름의 파일이 대상 경로에 이미 존재하는 경우 일반적으로 직접 덮어쓰게 됩니다. 실행하기 전에 이를 피하기 위해 이름을 바꿔야 하는지 확인해야 합니다.파이썬logging이 제품군은 애플리케이션의 효과적인 로그 관리를 위한 강력한 내장 세트입니다. 디버깅 정보 로깅, 오류 추적 또는 성능 모니터링 등logging각 제품군은 다중 레벨 및 다중 형식 로깅 방법을 제공할 수 있습니다.
DEBUG、INFO、WARNING、ERROR그리고CRITICAL。여기에 기본이 있습니다logging키트 구성 예:
수입 로깅
# 로거 설정
로거 = 로깅.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# 핸들러 설정
console_handler = 로깅.StreamHandler()
file_handler = 로깅.FileHandler('app.log')
# 포맷터 설정
formatter = 로깅.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(포맷터)
file_handler.setFormatter(포맷터)
# 로거에 핸들러 추가
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 다양한 수준의 로그 테스트
logger.debug('디버그 메시지입니다.')
logger.info('정보 메시지입니다.')
logger.warning('경고 메시지입니다.')
logger.error('오류 메시지입니다.')
logger.tical('심각한 메시지입니다')
logging다음 로그 수준이 지원됩니다.
DEBUG: 가장 낮은 수준으로 디버깅 정보에 사용됩니다.INFO: 시스템 작동 상태 등의 일반 정보입니다.WARNING: 경고 정보이지만 프로그램이 중지되지는 않습니다.ERROR: 일반적으로 오류로 인해 문제가 발생하는 오류 정보입니다.CRITICAL: 프로그램이 종료될 수 있는 가장 심각한 오류입니다.사용될 수 있다Formatter로그의 출력 형식을 정의하는 클래스입니다. 예를 들어:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
이 형식은 다음과 유사한 내용을 출력합니다.
2024-10-25 10:00:00 - my_logger - INFO - 안내 메시지입니다.
logging이 제품군은 다양한 로그 관리 옵션을 제공하므로 개발자는 필요에 따라 로그 수준, 출력 형식 및 대상을 사용자 정의할 수 있어 애플리케이션의 유지 관리 및 디버깅 효율성이 향상됩니다.
파이썬에서logging키트에는Handler로그의 출력 위치를 정의하는 핵심 구성요소입니다. 다양한 프로세서는 콘솔, 파일, 네트워크, 심지어 이메일을 포함한 다양한 대상으로 로그를 출력할 수 있습니다.StreamHandler가장 일반적으로 사용되는 프로세서 중 하나이며 콘솔에 로그를 출력하는 역할을 담당합니다.
존재하다logging, 일부 공통점Handler포함하다:
StreamHandler: 로그를 다음으로 출력합니다.stdout또는stderr(보통 콘솔).FileHandler: 로그를 파일로 출력합니다.NullHandler: 로그 출력을 무시합니다. 표시가 필요하지 않은 상황에 적합합니다.SMTPHandler: 이메일을 통해 로그를 보냅니다.StreamHandler콘솔 출력에 가장 일반적으로 사용되는 프로세서이며 일반적으로 로그 메시지를 표준 오류(stderr). 설정을 통해StreamHandler, 로그를 콘솔에 직접 표시할 수 있어 시스템 상태를 실시간으로 모니터링하는 데 적합합니다.
로그가 콘솔에 표시되는 것을 원하지 않으면 Logger에서 로그를 제거할 수 있습니다.StreamHandler, 또는 대신 사용NullHandler출력을 피하기 위해.
다음 예에서는 구성 방법을 보여줍니다.logging콘솔 출력을 제거하십시오.StreamHandler:
수입 로깅
# 로거 설정
로거 = 로깅.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# 콘솔에 출력하기 위해 StreamHandler를 추가합니다.
console_handler = 로깅.StreamHandler()
logger.addHandler(console_handler)
# 테스트 출력
logger.info("이 메시지는 콘솔에 표시됩니다")
# 콘솔 출력 제거
logger.removeHandler(console_handler)
logger.info("이 메시지는 콘솔에 표시되지 않습니다.")
사용될 수 있다NullHandler모든 로그 출력을 비활성화하려면:
수입 로깅
# Logger를 설정하고 NullHandler를 추가합니다.
로거 = 로깅.getLogger('my_logger')
logger.addHandler(logging.NullHandler())
# 이 메시지는 콘솔에 표시되지 않습니다
logger.info("이 메시지는 표시되지 않습니다.")
Handler예logging출력 위치를 정의하는 제품군의 구성 요소입니다. ~을 통해StreamHandler, 실시간 모니터링을 용이하게 하기 위해 로그 메시지를 콘솔에 표시할 수 있습니다. 콘솔 출력이 필요하지 않으면 제거할 수 있습니다.StreamHandler또는 사용NullHandler로깅 출력을 비활성화합니다.
login.Formatter에 스레드 ID를 포함하려면 다음을 사용할 수 있습니다.%(thread)d재산. 시스템에서 스레드에 할당한 고유한 정수 ID를 표시합니다.
수입 로깅
# 스레드 ID를 표시하려면 %(thread)d를 추가하세요.
log_formatter = 로깅.포맷터(
'%(asctime)s.%(msecs)03d %(thread)d %(levelno)s %(message)s',
"%Y-%m-%d %H:%M:%S"
)
#예제 출력:
# 2025-12-20 16:30:45.123 140735612345678 20 로그 메시지입니다
정수 ID 외에도 필요에 따라 스레드 이름을 표시하도록 선택할 수도 있습니다.
이 코드는 다중 스레드 환경에서 이 형식을 적용하는 방법을 보여줍니다.
수입 로깅
수입 스레딩
# 1. 포맷터 설정
log_format = '%(asctime)s.%(msecs)03d [스레드:%(thread)d] %(levelno)s %(message)s'
date_format = "%Y-%m-%d %H:%M:%S"
포맷터 = 로깅.포맷터(log_format, date_format)
# 2. 로그 프로세서 설정
핸들러 = 로깅.StreamHandler()
handler.setFormatter(포맷터)
로거 = 로깅.getLogger("ThreadTest")
logger.addHandler(핸들러)
logger.setLevel(logging.INFO)
# 3. 테스트 기능
데프 작업():
logger.info("하위 스레드가 실행 중입니다")
# 테스트 시작
logger.info("메인 스레드가 시작되었습니다")
t = 스레딩.스레드(대상=작업)
t.시작()
t.join()
Python에는 SQLite에 대한 지원이 내장되어 있으며 소규모 애플리케이션에 적합합니다.
import sqlite3
conn = sqlite3.connect("example.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
cursor.execute("INSERT INTO users (name) VALUES (?)", ("Alice",))
conn.commit()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
cursor.close()
conn.close()
MySQL 데이터베이스에 연결하는 데 사용됩니다.
pip install pymysql
import pymysql
conn = pymysql.connect(host="localhost", user="root", password="password", database="test")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
cursor.close()
conn.close()
PostgreSQL에 연결하는 데 사용됩니다.
pip install psycopg2
import psycopg2
conn = psycopg2.connect(dbname="testdb", user="user", password="password", host="localhost")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
cursor.close()
conn.close()
Microsoft SQL Server에 연결하는 데 사용됩니다.
pip install pyodbc
import pyodbc
conn = pyodbc.connect("DRIVER={SQL Server}; SERVER=localhost; DATABASE=test; UID=user; PWD=password")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
cursor.close()
conn.close()
파일 기반 데이터베이스에 적합합니다.
pip install pymongo
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["testdb"]
collection = db["users"]
collection.insert_one({"name": "Alice", "age": 25})
print(list(collection.find()))
캐싱 및 고성능 키-값 액세스에 적합합니다.
pip install redis
import redis
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
r.set("name", "Alice")
print(r.get("name"))
전체 텍스트 검색 및 분석에 적합합니다.
pip install elasticsearch
from elasticsearch import Elasticsearch
es = Elasticsearch("http://localhost:9200")
doc = {"name": "Alice", "age": 25}
es.index(index="users", document=doc)
print(es.search(index="users", query={"match_all": {}}))
다중 SQL 데이터베이스를 지원하고 ORM 기능을 제공합니다.
pip install sqlalchemy
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
engine = create_engine("sqlite:///example.db")
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
session.add(User(name="Alice"))
session.commit()
print(session.query(User).all())
sqlite3(내장),pymysql(MySQL)、psycopg2(PostgreSQL)、pyodbc(SQL Server)。pymongo(MongoDB)、redis(Redis)、elasticsearch(Elasticsearch)。SQLAlchemy(여러 SQL 데이터베이스 지원)다음 지침에 따라 PyMySQL을 설치합니다.
pip install pymysql
PyMySQL을 사용하여 MySQL 서버에 연결합니다.
importpymysql
# 연결 설정
conn = pymysql.connect(
호스트="로컬호스트",
사용자="귀하의_사용자",
비밀번호="귀하의_비밀번호",
데이터베이스="your_database",
charset="utf8mb4",
커서클래스=pymysql.cursors.DictCursor # 사전 형식을 반환합니다.
)
#커서 생성
커서 = conn.cursor()
# 쿼리 정보
커서.execute("SELECT * FROM your_table")
결과 = 커서.fetchall()
결과 행의 경우:
인쇄(행)
# 연결 닫기
커서.닫기()
연결.닫기()
INSERT, UPDATE 및 DELETE 문을 실행할 때 변경 사항을 제출해야 합니다.
시도해 보세요:
conn.cursor()를 커서로 사용:
sql = "INSERT INTO 사용자(이름, 나이) VALUES(%s, %s)"
커서.execute(sql, ("앨리스", 25))
conn.commit() # 변경 사항 제출
e와 같은 예외를 제외하고:
conn.rollback() # 오류 발생 시 롤백
print("오류가 발생했습니다:", e)
사용될 수 있다callproc저장 프로시저 호출:
with conn.cursor() as cursor:
cursor.callproc("your_stored_procedure", (param1, param2))
result = cursor.fetchall()
print(result)
사용executemany대량 삽입을 수행하려면 다음을 수행하십시오.
data = [("Bob", 30), ("Charlie", 28), ("David", 35)]
sql = "INSERT INTO users (name, age) VALUES (%s, %s)"
with conn.cursor() as cursor:
cursor.executemany(sql, data)
conn.commit()
SQL 삽입 공격을 방지하려면 매개변수화된 쿼리를 사용하세요.
name = "Alice"
sql = "SELECT * FROM users WHERE name = %s"
with conn.cursor() as cursor:
cursor.execute(sql, (name,))
result = cursor.fetchall()
print(result)
프로그램이 종료되면 데이터베이스 연결을 닫아야 합니다.
conn.close()
PyMySQL은 자동으로datetime.datetimeMySQL DATETIME으로 변환하고 직접 전달할 수 있습니다.
import pymysql
import datetime
conn = pymysql.connect(
host="localhost",
user="root",
password="pwd",
database="testdb",
cursorclass=pymysql.cursors.DictCursor
)
with conn:
with conn.cursor() as cur:
now = datetime.datetime.now()
sql = """
INSERT INTO logs (msg, created_at)
VALUES (%s, %s)
"""
cur.execute(sql, ("hello world", now))
conn.commit()
today = datetime.date.today()
sql = "INSERT INTO records (start_date) VALUES (%s)"
cur.execute(sql, (today,))
conn.commit()
찾은 필드는 자동으로datetime.datetime유형.
sql = "ID 선택, FROM 로그 ORDER BY ID DESC LIMIT 1"
현재 실행(sql)
행 = cur.fetchone()
dt = 행["created_at"]
인쇄(dt, 유형(dt))
# 예: 2025-07-01 15:22:33
formatted = dt.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)
start = datetime.datetime(2025, 1, 1, 0, 0, 0)
sql = """
SELECT * FROM logs
WHERE created_at >= %s
"""
cur.execute(sql, (start,))
rows = cur.fetchall()
begin = datetime.datetime(2025, 1, 1)
end = datetime.datetime(2025, 1, 31, 23, 59, 59)
sql = """
SELECT * FROM logs
WHERE created_at BETWEEN %s AND %s
"""
cur.execute(sql, (begin, end))
rows = cur.fetchall()
sql = "SELECT created_at FROM logs_str LIMIT 1"
cur.execute(sql)
row = cur.fetchone()
dt = datetime.datetime.strptime(row["created_at"], "%Y-%m-%d %H:%M:%S")
print(dt)
items = [
("log1", datetime.datetime.now()),
("log2", datetime.datetime.now()),
]
sql = "INSERT INTO logs (msg, created_at) VALUES (%s, %s)"
cur.executemany(sql, items)
conn.commit()
strptime수동 구문 분석.importpymysql
날짜/시간 가져오기
# 데이터베이스 연결 설정
conn = pymysql.connect(
호스트='로컬호스트',
사용자='루트',
비밀번호='your_password',
데이터베이스='your_db',
cursorclass=pymysql.cursors.DictCursor # 필드를 사전으로 반환
)
콘과 함께:
conn.cursor()를 커서로 사용:
sql = "ID 선택, your_table LIMIT 1에서 생성된_at"
커서.실행(sql)
결과 = 커서.fetchone()
dt = result['created_at'] # Created_at 필드가 날짜/시간 유형이라고 가정합니다.
인쇄(dt)
인쇄(유형(dt))
dt_str = dt.strftime("%Y-%m-%d %H:%M:%S")
print(dt_str)
# Create_at이 문자열 형식(예: CHAR/VARCHAR)으로 저장되는 경우
dt = datetime.datetime.strptime(result['created_at'], "%Y-%m-%d %H:%M:%S")
인쇄(dt)
# DictCursor가 설정되지 않은 경우 데이터는 튜플이 되며 값 방법은 다음과 같습니다.
커서 = conn.cursor()
cursor.execute("ID 선택, your_table에서 생성된_at")
행 = 커서.fetchone()
dt = 행[1]
importpymysql
날짜/시간 가져오기
# 데이터베이스 연결 설정
conn = pymysql.connect(
호스트='로컬호스트',
사용자='루트',
비밀번호='your_password',
데이터베이스='your_db',
커서클래스=pymysql.cursors.DictCursor
)
콘과 함께:
conn.cursor()를 커서로 사용:
sql = "your_table LIMIT 1에서 생성된_at을 선택하세요."
커서.실행(sql)
결과 = 커서.fetchone()
dt_from_sql = result['created_at'] # 날짜/시간 유형
지금 = datetime.datetime.now()
# 시차를 계산한다
diff = 현재 - dt_from_sql
print(f"일수 차이: {diff.days}")
diff = now.date() - dt_from_sql.date()
print(f"순수 날짜 차이 일수: {diff.days}")
importpymysql
날짜/시간 가져오기
# 데이터베이스 연결 설정
conn = pymysql.connect(
호스트='로컬호스트',
사용자='루트',
비밀번호='your_password',
데이터베이스='your_db',
커서클래스=pymysql.cursors.DictCursor
)
콘과 함께:
conn.cursor()를 커서로 사용:
sql = "your_table LIMIT 1에서 생성된_at을 선택하세요."
커서.실행(sql)
결과 = 커서.fetchone()
dt_from_sql = result['created_at'] # 날짜/시간 유형
지금 = datetime.datetime.now()
# 시차를 계산한다
diff = 현재 - dt_from_sql
시간 = diff.total_seconds() / 3600
print(f"시간 차이: {시간}")
print(f"차이는 정수 시간입니다: {int(hours)}")
MySQL의 기본 스토리지 엔진인 InnoDB에서 기본 격리 수준은 다음과 같습니다.REPEATABLE READ(반복 읽기).
이는 동일한 트랜잭션(트랜잭션)에서 첫 번째 쿼리를 실행한 후 MySQL이 트랜잭션의 "스냅샷"을 생성한다는 의미입니다. 1초 후에 다른 프로그램에 의해 데이터베이스의 데이터가 수정되더라도 트랜잭션이 종료되지 않는 한 두 번째 쿼리에서는 여전히 처음과 동일한 스냅샷 데이터를 볼 수 있습니다. 이는 "반복 읽기"의 일관성을 보장하기 위한 것입니다.
이것이 가장 표준적인 접근 방식입니다. 두 번째 쿼리를 실행하기 전에 다음을 호출하세요.connection.commit(). 제출하면 현재 트랜잭션이 종료되고 MySQL은 다음 쿼리 중에 새 스냅샷을 생성하고 최신 데이터를 읽습니다.
# 첫 번째 쿼리
커서.실행(sql)
결과1 = 커서.fetchall()
# 강제 업데이트: 현재 트랜잭션을 커밋합니다.
연결.커밋()
# 두 번째 쿼리는 최신 정보를 캡처합니다.
커서.실행(sql)
결과2 = 커서.fetchall()
모든 SQL 명령을 즉시 적용하고 최신 결과를 보려면 연결을 설정한 후 자동 제출을 켜면 됩니다. 그러니 다들execute()독립적인 사안으로 처리됩니다.
Connection.autocommit = 참
# 모든 후속 실행(sql)은 데이터베이스의 최신 상태를 직접 읽습니다.
격리 수준을 다음으로 변경할 수 있습니다.READ COMMITTED(커밋 내용 읽기) 이 수준에서는 동일한 트랜잭션 내에서 쿼리가 실행될 때마다 가장 최근에 제출된 데이터를 읽습니다.
# 쿼리를 실행하기 전에 설정
cursor.execute("세션 트랜잭션 격리 수준 설정 읽기 커밋됨")
connection(유선) 트랜잭션 범위가 아님cursor개체 자체. 커서를 다시 생성했지만 동일한 연결을 사용하고 커밋하지 않으면 문제가 여전히 존재합니다.Python의 다중 스레드 환경에서 여러 스레드가 동일한 데이터베이스 연결을 공유하면 심각한 충돌이 발생합니다. 이는 연결된 개체가 일반적으로 스레드로부터 안전하지 않기 때문입니다. 여러 스레드가 동시에 SQL 명령을 보내거나 결과를 읽으면 데이터 혼란, 트랜잭션 예외 또는 연결 중단이 발생할 수 있습니다. 따라서 연결 풀을 사용하여 각 스레드에 독립적인 연결을 할당하는 것이 가장 좋습니다.
mysql-connector-python간단한 연결 풀 기능이 내장되어 있습니다. 미리 풀을 생성하고 스레드에 필요할 때 풀에서 연결을 "대여"할 수 있습니다.
수입 스레딩
mysql.connector 가져오기
mysql.connector 가져오기 풀링에서
# 1. 연결 풀 생성(전역 변수)
db_config = {
"호스트": "로컬호스트",
"사용자": "루트",
"비밀번호": "비밀번호",
"데이터베이스": "테스트_db"
}
연결_풀 = mysql.connector.pooling.MySQLConnectionPool(
pool_name="my_pool",
pool_size=5, # 풀 크기를 설정합니다. 이 크기는 스레드 수보다 크거나 같아야 합니다.
**db_config
)
# 2. 스레드 작업 기능 실행
def thread_task(task_id):
conn=없음
시도해 보세요:
# 풀에서 독립적인 연결을 얻습니다.
conn = 연결_풀.get_connection()
커서 = conn.cursor()
# 작업 수행
커서.execute("지금 선택()")
결과 = 커서.fetchone()
print(f"실행 스레드 {task_id} 읽기 시간: {result}")
# 참고: 이 격리 수준에서는 변경 사항이 있으면 커밋하는 것을 기억하세요.
# conn.commit()
e와 같은 예외를 제외하고:
print(f"스레드 {task_id}에서 오류가 발생했습니다: {e}")
마지막으로:
# 중요: 커서와 연결을 닫습니다. (여기서 close는 연결을 실제로 중단하는 대신 풀에 대한 연결을 반환합니다.)
conn 및 conn.is_connected()인 경우:
커서.닫기()
연결.닫기()
# 3. 다중 실행 스레드 시작
스레드 = []
범위 내의 i에 대해(3):
t = 스레딩.Thread(대상=thread_task, args=(i,))
스레드.추가(t)
t.시작()
스레드의 t에 대해:
t.join()
대규모 애플리케이션을 개발하는 경우 SQLAlchemy는 더욱 강력하고 자동화된 연결 관리(QueuePool)를 제공합니다. 연결 실패, 재활용 및 스레드 할당을 자동으로 처리합니다.
sqlalchemy import create_engine에서
sqlalchemy.orm에서 세션 메이커 가져오기
# 엔진 생성 시 연결 풀이 자동으로 활성화됩니다.
엔진 = create_engine(
"mysql+mysqlconnector://root:password@localhost/test_db",
pool_size=10,
max_overflow=20
)
# 각 스레드가 독립적인 세션을 갖도록 세션메이커를 사용합니다.
세션 = 세션메이커(바인드=엔진)
def sqlalchemy_task():
세션 = 세션()
시도해 보세요:
# 작업 수행
# 세션.실행(...)
세션.커밋()
마지막으로:
session.close() # 연결을 반환합니다.
with예외가 발생하더라도 연결이 반환될 수 있도록 커서와 연결을 관리하는 구문입니다.commit()또는rollback()그렇지 않으면 풀로 반환될 때 연결이 완료되지 않은 트랜잭션 상태가 되어 다음 사용자에게 영향을 미칠 수 있습니다.Python에서 MySQL 저장 프로시저를 실행하려면 다음을 사용할 수 있습니다.mysql-connector-python또는PyMySQL。
pip install mysql-connector-python
mysql.connector 가져오기
# 데이터베이스에 연결
conn = mysql.connector.connect(
호스트="로컬호스트",
사용자="귀하의_사용자",
비밀번호="귀하의_비밀번호",
데이터베이스="your_database"
)
커서 = conn.cursor()
# 저장 프로시저 호출
커서.callproc("your_stored_procedure", (param1, param2))
# 결과 얻기
커서.stored_results()의 결과:
인쇄(결과.fetchall())
# 연결 닫기
커서.닫기()
연결.닫기()
Python에서 SQL Server 저장 프로시저를 실행하려면 다음을 사용할 수 있습니다.pyodbc。
pip install pyodbc
pyodbc 가져오기
# SQL 서버에 연결
conn = pyodbc.connect("DRIVER={SQL 서버};"
"SERVER=your_server;"
"DATABASE=your_database;"
"UID=your_user;"
"PWD=your_password")
커서 = conn.cursor()
# 저장프로시저를 실행한다
커서.execute("{CALL your_stored_procedure (?, ?)}", (param1, param2))
# 결과 얻기
행 = 커서.fetchall()
행의 행의 경우:
인쇄(행)
# 연결 닫기
커서.닫기()
연결.닫기()
Python에서 PostgreSQL 저장 프로시저를 실행하려면 다음을 사용할 수 있습니다.psycopg2。
pip install psycopg2
psycopg2 가져오기
# PostgreSQL에 연결
conn = psycopg2.connect(
dbname="your_database",
사용자="귀하의_사용자",
비밀번호="귀하의_비밀번호",
호스트="로컬호스트",
포트="5432"
)
커서 = conn.cursor()
# 저장프로시저를 실행한다
커서.callproc("your_stored_procedure", (param1, param2))
# 결과 얻기
행 = 커서.fetchall()
행의 행의 경우:
인쇄(행)
# 연결 닫기
커서.닫기()
연결.닫기()
fetchall()또는stored_results()결과를 얻으려면.requests이는 Python에서 가장 일반적으로 사용되는 HTTP 요청 모음으로, REST API에 액세스하고, 웹 페이지를 다운로드하고, 양식 데이터를 보내는 등의 작업에 사용됩니다. 내장된 것보다 낫습니다.urllib더욱 간결하고 사용하기 쉬워졌습니다.
pip install requests
수입요청
#GET 요청 보내기
URL = "https://api.pionex.com/api/v1/common/symbols"
응답 = 요청.get(url)
# 성공했는지 확인
response.status_code == 200인 경우:
데이터 = response.json()
print("요청 성공, 반환 필드:", list(data.keys()))
그 외:
print("요청 실패:", response.status_code)
import requests
url = "https://httpbin.org/post"
payload = {"key": "value", "symbol": "BTC_USDT"}
headers = {"Content-Type": "application/json"}
res = requests.post(url, json=payload, headers=headers)
print(res.json())
| 방법 | 사용 |
|---|---|
requests.get() | 정보 얻기(가장 일반적으로 사용됨) |
requests.post() | 정보 또는 양식 제출 |
requests.put() | 정보 업데이트 |
requests.delete() | 데이터 삭제 |
response.status_code | HTTP 상태 코드 |
response.json() | JSON 응답 구문 분석 |
response.text | 원본 텍스트 콘텐츠 가져오기 |
response.raise_for_status() | HTTP 오류 예외를 자동으로 발생시킵니다. |
수입요청
시도해 보세요:
r = 요청.get("https://api.pionex.com/api/v1/unknown")
r.raise_for_status()
e로 요청.예외.HTTPError를 제외합니다:
print("HTTP 오류:", e)
e로 요청.예외.RequestException을 제외합니다.
print("일반 요청 오류:", e)
pandas또는asyncio많은 양의 데이터를 검색하는 데 사용할 수 있습니다.raise_for_status()예requests모듈 내ResponseHTTP 응답 상태 코드가 오류(예: 4xx 또는 5xx)인지 확인하는 데 사용되는 개체의 메서드입니다.
상태 코드에 요청이 실패했음이 표시되면 자동으로 오류가 발생합니다.requests.exceptions.HTTPError예외는 디버깅이나 실행 중지를 용이하게 하는 데 사용됩니다.
수입요청
URL = "https://api.pionex.com/api/v1/common/symbols"
응답 = 요청.get(url)
# HTTP 상태 코드가 성공했는지 확인합니다(200~299).
response.raise_for_status()
# 성공하면 JSON을 안전하게 구문 분석할 수 있습니다.
데이터 = response.json()
print("요청이 성공했습니다. 획득한 거래 쌍 수:", len(data.get("data", [])))
요청이 성공했으며 획득한 거래 쌍 수: 248
수입요청
시도해 보세요:
r = 요청.get("https://api.pionex.com/api/v1/invalid_endpoint")
r.raise_for_status()
e로 요청.예외.HTTPError를 제외합니다:
print("HTTP 오류:", e)
e로 요청.예외.RequestException을 제외합니다.
print("예외 요청:", e)
HTTPError。수입요청
# 호출 API
URL = "https://api.example.com/data"
응답 = 요청.get(url)
# 응답이 성공했는지 확인
response.status_code == 200인 경우:
print("데이터를 성공적으로 얻었습니다.")
그 외:
print(f"오류: {response.status_code}")
# JSON 응답 구문 분석 데이터 = response.json() #JSON 데이터에 액세스 인쇄(데이터["key1"]) print(data["key2"]["하위 키"])
수입요청
# API URL
URL = "https://jsonplaceholder.typicode.com/posts"
# 요청 보내기
응답 = 요청.get(url)
# 응답 상태를 확인하고 구문 분석
response.status_code == 200인 경우:
데이터 = response.json()
# 각 기사의 제목을 나열합니다.
데이터 게시의 경우:
print(f"게시물 ID: {post['id']}, 제목: {post['title']}")
그 외:
print(f"API 호출 실패, 상태 코드: {response.status_code}")
시도해 보세요:
데이터 = response.json()
인쇄(데이터)
ValueError 제외:
print("응답이 유효한 JSON 형식이 아닙니다.")
파이썬이 제공하는json데이터를 JSON 형식으로 변환(직렬화)하는 모듈,
그리고 캐시 효과를 얻기 위해 파일로 저장(dump)하거나 다시 로드(load)할 수 있습니다.
json.dump(obj, file): Python 객체를 파일(JSON 형식)에 씁니다.json.dumps(obj): 객체를 JSON 문자열로 변환합니다.json.load(file): 파일에서 JSON을 읽고 이를 다시 Python 객체로 변환합니다.json.loads(str): JSON 문자열을 다시 Python 객체로 변환합니다.JSON 가져오기
수입 OS
캐시_파일 = "data_cache.json"
# 시뮬레이션 데이터 소스
데이터 = {
"이름": "앨리스",
"나이": 30,
"취미": ["독서", "음악", "코딩"]
}
#JSON 파일에 데이터 쓰기(덤프)
open(cache_file, "w", 인코딩="utf-8")을 f로 사용:
json.dump(data, f, verify_ascii=False, 들여쓰기=2)
print("데이터가 파일에 캐시되었습니다.")
# 파일에서 JSON 데이터 읽기(로드)
os.path.exists(cache_file)인 경우:
open(cache_file, "r", 인코딩="utf-8")을 f로 사용:
load_data = json.load(f)
print("로드된 데이터:",loaded_data)
데이터가 파일에 캐시되었습니다.
로드된 데이터: {'이름': '앨리스', '나이': 30, '취미': ['독서', '음악', '코딩']}
ensure_ascii=False: 한자가 유니코드 인코딩으로 변환되지 않도록 하세요.indent=2: JSON 파일을 들여쓰기하여 읽기 쉽게 만듭니다.json.load()JSON을 dict, list, int, str 등과 같은 해당 유형으로 자동 복원합니다.json,os 가져오기
CACHE_PATH = "result_cache.json"
def 비싼 계산():
print("복잡한 작업을 수행하는 중...")
[범위(5)의 x에 대해 x**2]를 반환합니다.
def get_cached_result():
#캐시가 있으면 로드합니다.
os.path.exists(CACHE_PATH)인 경우:
open(CACHE_PATH, "r")을 f로 사용:
json.load(f)를 반환합니다.
# 그렇지 않으면 계산 후 캐시에 쓰기
결과 = 비싼_계산()
open(CACHE_PATH, "w")를 f로 사용:
json.dump(결과, f)
결과 반환
데이터 = get_cached_result()
print("데이터 가져오기:", data)
복잡한 작업 수행...
데이터 가져오기: [0, 1, 4, 9, 16]
데이터 가져오기: [0, 1, 4, 9, 16]
json.dump():JSON 파일에 씁니다.json.load(): JSON 파일에서 읽습니다.dumps()그리고loads()문자열을 처리합니다.이는 일련의 레코드를 동일한 형식으로 저장하는 가장 표준적이고 일반적인 방법입니다. 모든 데이터 포인트를 목록(JSON의 해당 대괄호)으로 처리합니다.[]) 요소.
[
{"time": 1759028400000, "open": "109398.3", "close": "109364.8", "high": "109489.2", "low": "109364.8", "volume": "518.7594"},
{"time": 1759024800000, "open": "109305.6", "close": "109398.3", "high": "109496.4", "low": "109296.0", "volume": "757.0290"},
...
]
Python에서는 사전 목록을 작성한 다음 다음을 사용합니다.json.dumps()직렬화를 수행합니다.
import json
data_list = [
{'time': 1759028400000, 'open': '109398.3', 'close': '109364.8', 'high': '109489.2', 'low': '109364.8', 'volume': '518.7594'},
{'time': 1759024800000, 'open': '109305.6', 'close': '109398.3', 'high': '109496.4', 'low': '109296.0', 'volume': '757.0290'}
]
json_output = json.dumps(data_list, indent=4)
# print(json_output)
각 데이터 포인트의 경우time값은 고유하며 이를 최상위 개체의 키로 사용하여 사전 구조를 만들 수 있습니다. 이 구조는 타임스탬프를 통해 특정 데이터를 직접 쿼리하는 것을 용이하게 합니다.
{
"1759028400000": {"open": "109398.3", "close": "109364.8", "high": "109489.2", "low": "109364.8", "volume": "518.7594"},
"1759024800000": {"open": "109305.6", "close": "109398.3", "high": "109496.4", "low": "109296.0", "volume": "757.0290"},
...
}
데이터 목록을 반복하고 각 데이터 포인트를 변환해야 합니다.time값은 사전 키로 사용됩니다.
JSON 가져오기
소스_데이터 = [
{'시간': 1759028400000, '개시': '109398.3', '종료': '109364.8', '높음': '109489.2', '낮음': '109364.8', '볼륨': '518.7594'},
{'시간': 1759024800000, '개시': '109305.6', '종료': '109398.3', '높음': '109496.4', '낮음': '109296.0', '볼륨': '757.0290'}
]
data_dict = {}
source_data 항목의 경우:
# JSON 키는 문자열이어야 하므로 타임스탬프가 문자열인지 확인하세요.
time_key = str(항목['시간'])
# 새 사전을 복사하거나 생성하고 'time' 필드가 이제 핵심이므로 제거합니다.
value_data = item.copy()
del value_data['시간']
data_dict[time_key] = 값_데이터
json_output = json.dumps(data_dict, 들여쓰기=4)
# 인쇄(json_output)
Python에서는 내장된json모듈은 목록 및 사전과 같은 Python 데이터 구조를 JSON 형식으로 직렬화하는 가장 좋은 방법입니다. 대상 구조는 Python에서 사전이 포함된 목록에 해당합니다.
데이터베이스 쿼리에서 얻은 데이터가 이미 목록이고 각 요소가 사전이며 키 이름이 원하는 JSON 필드 이름과 일치한다고 가정합니다.
db_data = [
{'시간': 1759028400000, '개시': '109398.3', '종료': '109364.8', '높음': '109489.2', '낮음': '109364.8', '볼륨': '518.7594'},
{'시간': 1759024800000, '개시': '109305.6', '종료': '109398.3', '높음': '109496.4', '낮음': '109296.0', '볼륨': '757.0290'},
# ... 추가 데이터
]
json.dumps()수입만 하면 된다json모듈 및 사용json.dumps()함수는 Python 목록 개체를 JSON 형식의 문자열로 변환합니다.
JSON 가져오기
# db_data가 준비되었다고 가정합니다.
# json.dumps()를 사용하여 Python 목록을 JSON 문자열로 직렬화합니다.
# indent=4는 출력을 아름답게 하고 읽기 쉽게 만드는 데 사용됩니다.
json_output_string = json.dumps(db_data, 들여쓰기=4)
인쇄(json_output_string)
그러면 목표와 일치하는 JSON 문자열이 생성됩니다.
[
{
"time": 1759028400000,
"open": "109398.3",
"close": "109364.8",
"high": "109489.2",
"low": "109364.8",
"volume": "518.7594"
},
{
"time": 1759024800000,
"open": "109305.6",
"close": "109398.3",
"high": "109496.4",
"low": "109296.0",
"volume": "757.0290"
}
]
데이터베이스 드라이버가 튜플 목록을 반환하는 경우(예:[(1759028400000, '109398.3', ...), ...]), 위의 직렬화를 수행하기 전에 사전 목록으로 변환해야 합니다.
# 필드 이름이 다음과 같다고 가정합니다.
field_names = ['시간', '시가', '종가', '높음', '낮음', '볼륨']
tuple_data = [
(1759028400000, '109398.3', '109364.8', '109489.2', '109364.8', '518.7594'),
#...
]
# 목록 이해
list_of_dicts = [
dict(zip(필드 이름, 행))
Tuple_data의 행에 대해
]
# 이제 직렬화를 위해 list_of_dicts를 json.dumps()에 직접 전달할 수 있습니다.
Python에서 웹 API를 구현하고 JSON을 출력하는 방법은 사용하는 프레임워크에 따라 다릅니다. 대부분은 PHP에 직접적으로 해당합니다.echo json_encode()논리는 Python을 사용하여 내장되어 있습니다.json모듈이지만 웹 환경에서는 일반적으로 헤더가 프레임워크에서 제공하는 도구를 통해 자동으로 처리됩니다.
FastAPI는 최신 Python 개발을 위한 첫 번째 선택이며 Python의dict(사전) 또는list(목록)을 JSON으로 변환하고 올바른 값을 설정하세요.Content-Type。
fastapi에서 FastAPI 가져오기
앱 = FastAPI()
@app.get("/api/stocks")
def get_stocks():
# Python 사전을 직접 반환하면 FastAPI가 자동으로 json_encode를 처리합니다.
데이터 = ["AAPL", "TSLA", "NVDA", "GOOGL"]
{"주식": 데이터}를 반환합니다.
Flask에서 공식적으로 제공jsonify함수를 사용하면 데이터를 변환하는 것 외에도 응답 헤더를 다음과 같이 설정하는 데 도움이 됩니다.application/json。
플라스크 가져오기 플라스크, jsonify에서
앱 = 플라스크(__name__)
@app.route('/api/stocks')
def get_stocks():
데이터 = ["AAPL", "TSLA", "NVDA", "GOOGL"]
# PHP의 echo json_encode($data)와 동일하며 헤더를 추가합니다.
jsonify(데이터) 반환
대규모 프레임워크인 Django를 사용하는 경우 일반적으로 다음을 사용합니다.JsonResponse물체.
from django.http import JsonResponse
def stock_api(request):
data = {"stocks": ["AAPL", "TSLA"]}
return JsonResponse(data)
단순히 JSON 문자열(예: 파일 쓰기 또는 사용자 정의 출력)을 얻으려면 다음을 사용할 수 있습니다.json.dumps()。
JSON 가져오기
data = {"이름": "쌍둥이자리", "나이": 18}
# 이는 PHP json_encode()의 저수준 구현에 가장 가깝습니다.
json_string = json.dumps(데이터)
인쇄(json_string)
| 기능 | PHP (Vanilla) | Python (FastAPI / Flask) |
|---|---|---|
| JSON 헤더 설정 | header('Content-Type: application/json') |
프레임 자동 처리(사용return dict또는jsonify) |
| 객체를 JSON 문자열로 | json_encode($data) |
json.dumps(data) |
| 출력 및 종료 | echo ...; exit; |
return ... |
return사전을 사용하면 모든 형식 변환을 처리할 수 있습니다.Google API는 주로 Google Cloud Platform(GCP)을 통해 제공되는 서비스로, 개발자가 Google의 다양한 기능(검색, 지도, 클라우드 드라이브 등)에 접근할 수 있도록 해줍니다. 대부분의 Google API는 RESTful 아키텍처를 따르며 데이터 교환에 JSON 형식을 사용합니다.
Google API를 사용하기 전에 먼저 Google Cloud Console에서 프로젝트를 만들고 인증 방법을 설정해야 합니다. 주로 두 가지 유형으로 나뉩니다.
Python에서는 개발을 단순화하기 위해 다음 라이브러리가 공식적으로 권장됩니다.
google-api-python-client: 대부분의 Discovery 서비스를 위한 범용 API 클라이언트입니다.google-auth: 인증 및 토큰 관리를 전문적으로 처리합니다.google-cloud-storage / google-cloud-vision: 특정 클라우드 서비스에 최적화된 클라이언트 라이브러리입니다.pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib。execute()。Google API는 완전히 무료이거나 무제한이 아닙니다. 각 API에는 고유한 할당량 청구 방법이 있습니다.
| 범주 | 대표 API | 주요 목적 |
|---|---|---|
| 업무 자동화 | Google Sheets / Calendar / Gmail | 양식, 일정을 자동화하고 이메일을 보냅니다. |
| 데이터 및 스토리지 | Cloud Storage / BigQuery | 대용량 파일을 저장하고 빅데이터 분석을 수행합니다. |
| 일체 포함 | Vision / Translation / Natural Language | 이미지 인식, 텍스트 번역, 감정 분석. |
| 멀티미디어 | YouTube Data API | 비디오를 검색하고 채널 콘텐츠를 관리하세요. |
일반적으로 다음을 통해 Python에서 Google API(예: YouTube, Drive, Gmail 등)를 사용합니다.google-api-python-client도서관에서build서비스 객체를 생성하는 함수입니다. 이 개체는 모든 API 메소드를 캡슐화하며 Google 서버와의 주요 통신 채널입니다.
서비스 객체를 생성하려면 API 이름, 버전, 인증 키(API Key) 또는 자격 증명(OAuth2)이 필요합니다.
googleapiclient.discovery 가져오기 빌드에서
# YouTube 데이터 API v3 초기화
유튜브 = 빌드(
'유튜브',
'v3',
개발자키='YOUR_API_KEY'
)
# 호출 API 예시
요청 = youtube.videos().list(part="snippet", id="dQw4w9WgXcQ")
응답 = request.execute()
이것이 이전에 충돌을 경험한 핵심 이유입니다.build()생성된 서비스 객체와 그 내부http전송 계층 객체스레드로부터 안전하지 않음의. 다중 스레드 환경에서는 다음 지침을 따르십시오.
youtube.execute()。run()메소드에서 실행됨build()。googleapiclient.discovery.Resource예.자주 전화하다build()"발견 문서"의 반복 다운로드로 인해 성능이 저하됩니다(약 1~2초의 추가 지연). 다음을 통해 최적화할 수 있습니다.
# 탐색 파일 다운로드 비활성화(미리 컴파일된 라이브러리를 설치했거나 작업 속도를 높이려는 경우)
# 참고: 이를 위해서는 환경에 관련 정의가 이미 있어야 합니다.
youtube = build('youtube', 'v3', 개발자키='KEY', static_discovery=True)
서비스 메소드를 호출할 때 발생하는 가장 일반적인 오류는 다음과 같습니다.HttpError. 할당량 소진이나 권한 문제를 처리하려면 이를 포착해야 합니다.
googleapiclient.errors에서 HttpError 가져오기
시도해 보세요:
응답 = youtube.channels().list(part="statistics", 광산=True).execute()
e로 HttpError를 제외하고:
e.resp.status == 403인 경우:
print("API 할당량이 소진되었거나 권한이 부족합니다.")
elif e.resp.status == 401:
print("인증이 잘못되었습니다.")
그 외:
print(f"HTTP 오류: {e}")
| API 기능 | 이름 매개변수 | 버전 매개변수 |
|---|---|---|
| YouTube Data | 'youtube' | 'v3' |
| Google Drive | 'drive' | 'v3' |
| Google Sheets | 'sheets' | 'v4' |
| Gmail API | 'gmail' | 'v1' |
여러 스레드에서 동일한 Google API 서비스 개체를 공유하는 경우(예:YoutubeApi.youtube), 스레드 안전성 문제가 발생할 수 있습니다. 맨 아래httplib2또는urllib3여러 스레드가 동일한 연결 개체에 동시에 액세스할 때 전송 계층은 경쟁 조건(Race Condition)을 생성하여 프로그램이 기본 네트워크 계층에서 직접 충돌하게 만듭니다. 때로는 C 언어 수준에서 오류가 발생하여 Python 인터프리터가 직접 닫히는 경우도 있습니다. 이것이 바로 이유이다try...except가로챌 수 없는 이유.
메인 스레드에서 전역 도메인을 생성하지 마세요youtube객체는 누구나 사용할 수 있습니다. 각 스레드는 시작될 때 자체 API 서비스 인스턴스를 생성해야 합니다. 이러한 방식으로 각 스레드는 서로 간섭하지 않고 자체 네트워크 연결과 캐시를 갖습니다.
수입 스레딩
googleapiclient.discovery 가져오기 빌드에서
데프 get_youtube_service():
# 독립적인 객체를 생성하기 위해 각 스레드에서 내부적으로 이 함수를 호출합니다.
반환 빌드('youtube', 'v3', 개발자키='YOUR_API_KEY')
def thread_task(video_id):
시도해 보세요:
# 실행 스레드 내에서 전용 서비스를 생성합니다.
local_youtube = get_youtube_service()
요청 = local_youtube.videos().list(
part="snippet,통계",
id=video_id
)
응답 = request.execute()
print(f"성공적으로 획득: {video_id}")
e와 같은 예외를 제외하고:
print(f"스레드 오류: {e}")
# 다중 스레드 시작
t1 = 스레딩.Thread(target=thread_task, args=("vid1",))
t2 = 스레딩.Thread(target=thread_task, args=("vid2",))
t1.시작()
t2.시작()
객체를 반복적으로 생성하지 않으려면 다음을 사용할 수 있습니다.threading.Lock동시에 하나의 스레드만 실행할 수 있는지 확인하십시오.execute(). 이로 인해 API 호출이 대기열에 들어가게 되지만(동시성 가속 효과가 손실됨) 충돌이 발생하지 않습니다.
수입 스레딩
# 전역 잠금을 생성합니다
api_lock = threading.Lock()
def thread_task_with_lock(video_id):
# 잠금이 자동으로 해제되도록 하려면 with를 사용하세요.
api_lock 사용:
시도해 보세요:
요청 = YoutubeApi.youtube.videos().list(
부분="부분",
id=video_id
)
vlist = request.execute()
e와 같은 예외를 제외하고:
print(f"오류: {e}")
이전 버전의 클라이언트 라이브러리를 사용하는 경우 서비스를 빌드할 때 이를 명시적으로 지정할 수 있습니다.http이의를 제기하고 스레드가 아닌 안전한 것으로 만들거나 사용하십시오.httplib2.Http()독립 인스턴스. 그러나 이는 일반적으로 더 복잡하므로 옵션 1에 우선순위를 부여하는 것이 좋습니다.
socket.setdefaulttimeout(10), 네트워크 정체로 인해 특정 실행 스레드가 리소스를 영구적으로 점유하는 것을 방지합니다.pip install smtplib email
이 두 모듈은 일반적으로 Python에 내장되어 있으며 추가 설치가 필요하지 않습니다.
smtplib 가져오기
email.mime.text에서 MIMEText 가져오기
email.mime.multipart에서 MIMEMultipart 가져오기
# 보내는 사람, 받는 사람, 제목, 내용 설정
발신자 = '[email protected]'
수신자 = '[email protected]'
제목 = '테스트 이메일'
body = '파이썬에서 보낸 테스트 이메일입니다. '
# 이메일 콘텐츠 만들기
msg = MIMEMultipart()
msg['보낸 사람'] = 보낸 사람
msg['받는 사람'] = 수신자
msg['제목'] = 제목
msg.attach(MIMEText(body, '일반'))
#Gmail SMTP를 사용하여 보내기
smtp_server = 'smtp.gmail.com'
smtp_port=587
사용자 이름 = '[email protected]'
비밀번호 = 'your_app_password' # 일반 비밀번호 대신 앱 비밀번호 사용을 권장합니다.
smtplib.SMTP(smtp_server, smtp_port)를 서버로 사용:
서버.starttls()
server.login(사용자 이름, 비밀번호)
server.send_message(msg)
print('이메일이 전송되었습니다')
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib필터는 Gmail API를 통해 생성할 수 있습니다. 예를 들어 발신자가 특정 편지함인 경우 자동으로 라벨을 추가합니다.
googleapiclient.discovery 가져오기 빌드에서
google_auth_oauthlib.flow에서 InstalledAppFlow 가져오기
google.auth.transport.requests 가져오기 요청에서
수입 OS
수입 피클
# 필수 권한 범위
범위 = ['https://www.googleapis.com/auth/gmail.settings.basic',
'https://www.googleapis.com/auth/gmail.modify']
def gmail_service():
자격 증명=없음
os.path.exists("token.pickle")인 경우:
open("token.pickle", "rb")를 토큰으로 사용:
creds = pickle.load(토큰)
creds가 아니거나 creds.valid가 아닌 경우:
creds 및 creds.expired 및 creds.refresh_token인 경우:
creds.refresh(요청())
그 외:
흐름 = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
creds = flow.run_local_server(포트=0)
open("token.pickle", "wb")을 토큰으로 사용:
pickle.dump(creds, 토큰)
return build("gmail", "v1", 자격 증명=creds)
# Gmail 필터 만들기
def create_filter():
서비스 = gmail_service()
filter_config = {
"기준": {
"from": "[email protected]" # 조건: 보낸 사람
},
"액션": {
"addLabelIds": ["Label_123456"], # Gmail 내부 라벨 ID
"removeLabelIds": ["INBOX"] # 선택 사항: 받은 편지함 제거
}
}
결과 = service.users().settings().filters().create(
userId="나",
본문=filter_config
).실행()
print("성공적으로 생성되었습니다. 필터 ID:", result["id"])
__name__ == "__main__"인 경우:
create_filter()
Label_123456Gmail의 라벨 ID는 다음을 통해 액세스할 수 있습니다.users().labels().list()얻다.Gmail API로 생성된 규칙(필터)은 새 이메일이 들어올 때 자동으로 실행되며 추가 "실행"이 필요하지 않습니다.
Gmail API를 사용하여 일치하는 메일을 검색한 다음 일괄적으로 라벨을 지정하거나 이동하세요.
googleapiclient.discovery 가져오기 빌드에서
google_auth_oauthlib.flow에서 InstalledAppFlow 가져오기
google.auth.transport.requests 가져오기 요청에서
수입 OS
수입 피클
범위 = ['https://www.googleapis.com/auth/gmail.modify']
def gmail_service():
자격 증명=없음
os.path.exists("token.pickle")인 경우:
open("token.pickle", "rb")를 토큰으로 사용:
creds = pickle.load(토큰)
creds가 아니거나 creds.valid가 아닌 경우:
creds 및 creds.expired 및 creds.refresh_token인 경우:
creds.refresh(요청())
그 외:
흐름 = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
creds = flow.run_local_server(포트=0)
open("token.pickle", "wb")을 토큰으로 사용:
pickle.dump(creds, 토큰)
return build("gmail", "v1", 자격 증명=creds)
#기존 이메일에 Gmail 규칙 적용
def run_rule():
서비스 = gmail_service()
# from:[email protected]과 같은 검색 기준
쿼리 = "from:[email protected]"
결과 = service.users().messages().list(userId="me", q=query).execute()
메시지 = 결과.get("메시지", [])
메시지가 아닌 경우:
print("기준과 일치하는 이메일이 없습니다.")
반환
메시지의 메시지:
service.users().messages().modify(
userId="나",
id=msg["ID"],
본문={
"addLabelIds": ["Label_123456"], # 새 라벨 추가
"removeLabelIds": ["INBOX"] # 받은 편지함 제거
}
).실행()
print(f"{len(messages)} 메시지가 처리됨")
__name__ == "__main__"인 경우:
실행_규칙()
q조건 및 일괄 수정.from:, subject:, has:attachment。Python에서 HTTP API 서버를 구축하는 가장 일반적이고 권장되는 방법은 효율적이고 기능이 풍부한 웹 프레임워크를 사용하는 것입니다. 다음은 세 가지 주류 프레임워크와 그 특성을 소개합니다.
FastAPI는 API 구축을 위한 현대적이고 빠른(Starlette 및 Pydantic 기반) 웹 프레임워크입니다. 기본적으로 비동기 작업(async/await)을 지원하고 OpenAPI(Swagger UI) 파일을 자동으로 생성합니다.
# 설치: pip install fastapi uvicorn
fastapi에서 FastAPI 가져오기
앱 = FastAPI()
# 루트 경로 정의(GET 요청)
@app.get("/")
def read_root():
return {"안녕하세요": "세계"}
# 매개변수를 사용하여 경로를 정의합니다.
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = 없음):
반환 {"item_id": item_id, "q": q}
# 실행 서버 (파일명이 main.py라고 가정)
# 터미널에서 실행: uvicorn main:app --reload
Flask는 핵심을 단순하게 유지하고 개발자가 데이터베이스 및 검증 라이브러리와 같은 구성 요소를 자유롭게 선택할 수 있도록 하는 마이크로 프레임워크입니다. 높은 수준의 사용자 정의가 필요한 소규모 프로젝트나 애플리케이션에 적합합니다.
# 설치: pip 설치 플라스크
플라스크 가져오기에서 플라스크, jsonify, 요청
앱 = 플라스크(__name__)
#API 경로 정의
@app.route("/data", 메소드=['GET'])
def get_data():
return jsonify({"message": "이것은 Flask API 데이터입니다"})
#POST 경로 정의
@app.route("/submit", 메소드=['POST'])
def post_data():
데이터 = request.get_json()
return jsonify({"received": data}), 201
#서버실행
# if __name__ == '__main__':
# app.run(debug=True)
DRF는 완전한 기능을 갖춘 Django 웹 프레임워크를 기반으로 RESTful API를 빠르게 구축하기 위한 강력한 도구입니다. 직렬 변환기, 모델 보기 세트, 인증 및 권한 제어와 같은 대규모 API에 필요한 모든 기능을 제공합니다.
참고: DRF 샘플 코드는 더 길고 Django 프로젝트 및 애플리케이션을 먼저 생성해야 하므로 여기서는 생략하지만 대규모 프로젝트의 경우 첫 번째 선택입니다.
FastAPI에 대한 관용적 접근 방식은 데코레이터를 사용하는 것이지만@app.get()함수를 직접 장식하지만 대규모 애플리케이션을 더 잘 구성하고 구조화하기 위해(특히 종속성 주입 또는 경로 모듈화를 사용하는 경우) 종종 "APIRouter" 패턴 또는 "클래스 기반 뷰"라고 불리는 경로 핸들러를 클래스에 캡슐화할 수 있습니다.
**를 사용해야 합니다.fastapi.APIRouter** 및 **메서드 데코레이터**를 사용하여 이를 달성합니다.
우리는 사용할 것이다APIRouter경로를 정의한 다음 클래스 메서드를 핸들러로 등록합니다.
# 설치: pip install fastapi uvicorn
fastapi import APIRouter, FastAPI, 종속됨
import 주석을 입력하여
# 1단계: APIRouter 인스턴스 생성
라우터 = API라우터(
prefix="/api/v1", # 이 라우팅 그룹의 접두사를 설정합니다.
Tags=["items"] # 파일 분류에 사용됩니다.
)
# 2단계: 라우팅 로직을 포함하는 카테고리 정의
클래스 ItemService:
"""모든 품목 관련 비즈니스 로직 및 라우팅 처리를 처리합니다."""
def __init__(self, db_dependent: str):
# 의존성 주입 시뮬레이션(Dependency Injection)
self.db_connection = db_종속성
# @router.get을 사용하여 클래스 메소드를 장식합니다.
@router.get("/")
def read_root(self):
# read_root 로직 구현
return {"message": "ItemService 클래스의 Hello World!", "db_status": self.db_connection}
# read_item 로직 구현
# 매개변수 {item_id}는 URL 경로에서 옵니다
@router.get("/{item_id}")
def read_item(self, item_id: int, q: str | None = None):
반환 {
"항목_ID": 항목_ID,
"쿼리": q,
"status": "처리가 완료되었습니다"
}
#보조 기능: 종속성 주입 시뮬레이션(Dependency)
데프 get_db():
# 실제로 이는 데이터베이스 연결을 반환합니다.
"데이터베이스가 성공적으로 연결되었습니다"를 반환합니다.
# 3단계: 클래스 인스턴스에 대한 팩토리 함수 생성 및 종속성 주입
# Annotated[str, dependency(get_db)]는 db_connection이 get_db에 의해 제공됨을 나타냅니다.
def get_item_service(db_connection: 주석 처리됨[str, 종속(get_db)]):
# ItemService의 인스턴스를 반환합니다.
ItemService(db_connection) 반환
# 4단계: FastAPI 애플리케이션 주체 생성
앱 = FastAPI()
# 5단계: 핵심! 종속 항목을 사용하여 ItemService 클래스의 메서드를 애플리케이션에 탑재합니다.
# 여기서는 FastAPI가 ItemService의 인스턴스를 얻는 방법을 알 수 있도록 종속 항목이 사용됩니다.
app.include_router(
라우터,
종속성=[종속됨(get_item_service)]
)
위의 코드를 다음과 같이 저장하세요.main.py, Uvicorn 서버를 실행합니다.
uvicorn main:app --reload
ItemService.read_root방법.ItemService.read_item방법.이 패턴의 핵심은 다음과 같습니다.
APIRouter경로를 정의합니다.@router.get/@router.post그리고 다른 데코레이터.app.include_router~의dependencies매개변수.이것의 장점은 비즈니스 로직(ItemService(내부)는 라우팅 정의와 분리되어 프로그램 코드의 모듈화 및 테스트 가능성을 향상시킵니다.
터미널에서 Flask 애플리케이션을 실행하고 `app.run()`을 사용하여 시작한 경우 가장 쉬운 방법은 키보드 인터럽트 신호를 사용하는 것입니다.
특정 작업을 수행한 후 서버를 자동으로 종료해야 하는 단위 테스트나 시나리오에서는 코드를 통해 중지 명령을 보내야 합니다.
Flask에 내장된 개발 서버는 실제로 Werkzeug 라이브러리를 사용합니다. 특정 HTTP 요청을 서버에 보내 서버가 스스로 종료되도록 할 수 있습니다. 이를 위해서는 애플리케이션에서 특별한 경로를 정의해야 합니다.
플라스크 가져오기 플라스크에서 요청
앱 = 플라스크(__name__)
# 비밀 종료 경로를 정의합니다.
@app.route('/shutdown', 메소드=['POST'])
def shutdown_server():
# 승인된 사용자만 이 엔드포인트를 호출할 수 있는지 확인하세요.
func = request.environ.get('werkzeug.server.shutdown')
func가 None인 경우:
raise RuntimeError('Werkzeug 개발 서버에서 실행되지 않습니다')
func() # 닫기 함수 호출
return '서버가 종료됩니다...'
# ... 다른 경로 ...
# 다른 프로그램이나 스크립트에서 http://127.0.0.1:5000/shutdown으로 POST 요청을 보내 서버를 종료합니다.
기본적으로 `app.run()`은 차단됩니다. 서버가 백그라운드에서 실행되는 동안 기본 코드에서 다른 논리를 계속 실행하려면 다음을 사용해야 합니다.threading또는multiprocessing개조.
수입 스레딩
수입 시간
플라스크 가져오기 플라스크에서
앱 = 플라스크(__name__)
# ...당신의 경로 ...
def run_server():
# 참고: debug=True는 프로덕션 환경에서 사용하면 안 됩니다.
app.run(포트=5000)
# 새 스레드에서 서버를 시작합니다.
스레드 = threading.Thread(대상=run_server)
스레드.시작()
print("Flask 서버가 백그라운드에서 시작되었습니다...")
# 잠시 동안 서버를 실행해 보세요.
시간.수면(5)
# (프로그램 종료) 이 스레드 모드에는 내장된 단순 종료 기능이 없습니다.
# 위의 /shutdown 경로를 사용하거나 스레드를 직접 종료해야 합니다(권장되지 않으며 깨끗하지 않을 수 있음).
# 예: 서버 스레드가 끝날 때까지 기다립니다(Ctrl+C를 눌러 중지한 후).
# 스레드.조인()
프로덕션 환경에서는 `app.run()`을 사용하지 않습니다. WSGI 서버(예: Gunicorn 또는 uWSGI)를 사용합니다. 이러한 서버를 중지하려면 다음을 수행하세요.
Flask 애플리케이션이 기본 Werkzeug 개발 서버(예: Gunicorn, uWSGI 또는 기타 ASGI 서버를 사용하는 프로덕션 환경)에서 실행되지 않는 경우 현재 환경을 확인하는 가장 신뢰할 수 있는 방법은 **WSGI/ASGI 환경 변수**(예:request.environ또는request.scope)。
request.environ(Gunicorn 등 WSGI 서버에 적용)Flask 경로 기능에서는 다음 항목에 액세스할 수 있습니다.request.environ서버 유형을 결정하기 위해 WSGI 서버에서 설정한 특정 키를 확인하는 사전입니다.
플라스크 가져오기 플라스크, 요청, jsonify에서
앱 = 플라스크(__name__)
@app.route('/server_info')
def get_server_info():
# 기본값: Werkzeug 개발 서버를 가정합니다.
server_name = "Werkzeug(개발 서버)"
# 공통 WSGI 서버 식별자를 확인합니다.
# 건니콘을 확인하세요
request.environ에서 'gunicorn.version'인 경우:
server_name = f"Gunicorn (버전: {request.environ.get('gunicorn.version')})"
# uWSGI를 확인하세요
request.environ의 elif 'uwsgi.version':
# uWSGI에는 일반적으로 표준 버전 키가 없지만 특정 환경 변수가 있습니다.
server_name = "uWSGI"
# 웨이트리스 확인(공통 프로덕션 WSGI 서버)
request.environ의 elif 'waitress.version':
server_name = f"웨이트리스 (버전: {request.environ.get('waitress.version')})"
# 다른 WSGI 서버의 공통 식별자를 확인합니다.
request.environ의 elif 'SERVER_SOFTWARE':
# 많은 서버가 이 표준 WSGI 키를 설정합니다.
server_name = request.environ.get('SERVER_SOFTWARE')
# werkzeug.server.shutdown이 존재한다면 Werkzeug인 것이 거의 확실합니다.
request.environ의 elif 'werkzeug.server.shutdown':
server_name = "Werkzeug (개발서버, 종료 가능)"
jsonify({
"현재_서버": 서버_이름,
"is_dev_server": (server_name.startswith("Werkzeug"))
})
# 애플리케이션을 시작합니다
# if __name__ == '__main__':
# app.run(debug=True)
서버 종료 로직에서 이 검사를 직접 사용하여 `shutdown_func` 실행 여부를 결정할 수 있습니다.
플라스크 가져오기 요청에서 jsonify
@app.route('/shutdown', 메소드=['POST'])
def shutdown_server():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
shutdown_func가 없음인 경우:
# Werkzeug가 아닌 환경(일반적으로 프로덕션 환경)
jsonify({
"error": "이 끝점은 개발 환경 전용입니다. 서버를 중지하려면 운영 체제 명령을 사용하십시오."
}), 400
#Werkzeug환경
종료_기능()
return jsonify({"message": "서버가 종료 중입니다..."}), 200
`SERVER_SOFTWARE`는 표준 WSGI 환경 변수이지만 반드시 모든 서버에서 설정되는 것은 아니며, 설정 형식이 반드시 표준인 것은 아닙니다. 특정 서버 구성(예: `gunicorn.version`)에 대한 고유 키를 확인하는 것이 가장 안정적인 방법입니다.
Flask에서는 URL의 쿼리 문자열 매개변수(예:/my_api?abc=3&def=xy~에abc그리고def) 주요 도구는 다음과 같습니다.flask모듈식request물체. 당신은 사용할 수 있습니다request.args이러한 매개변수에 액세스하기 위한 사전입니다.
request.args사전request.args물음표(?) 모든 키-값 쌍 뒤에.
플라스크 가져오기 플라스크, 요청, jsonify에서
앱 = 플라스크(__name__)
@app.route('/my_api', 메소드=['GET'])
def get_query_parameters():
#전체 쿼리 매개변수 사전에 액세스
all_params = request.args
print(f"모든 매개변수: {all_params}")
# --- 특정 매개변수를 얻는 방법 ---
# 1. .get()을 사용하여 매개변수를 얻습니다(권장: 안전하고 기본값을 제공함)
# 'abc' 매개변수를 가져옵니다. 존재하지 않는 경우 기본값은 None입니다.
abc_value = request.args.get('abc')
# 'def' 매개변수를 가져옵니다. 존재하지 않는 경우 기본값은 'default_value'입니다.
def_value = request.args.get('def', 'default_value')
# 2. []를 사용하여 직접 액세스합니다. (권장하지 않음: 매개변수가 없으면 KeyError가 발생합니다.)
# 시도해 보세요:
# 필수_파라미터 = request.args['required']
# KeyError 제외:
# 필수_param = "누락"
# --- 다중 값 매개변수 처리 ---
# URL이 /my_api?item=apple&item=banana인 경우
item_list = request.args.getlist('item') # ['apple', 'banana']를 반환합니다.
jsonify({
"상태": "성공",
"abc": abc_값,
"def": def_value,
"항목_목록": 항목_목록
})
__name__ == '__main__'인 경우:
# 테스트 URL 1: http://127.0.0.1:5000/my_api?abc=3&def=xy&item=A&item=B
# 테스트 URL 2: http://127.0.0.1:5000/my_api
app.run(디버그=True)
| 방법 | 사용 | 행동 | 예 |
|---|---|---|---|
request.args.get('key') |
단일 매개변수를 안전하게 가져오기 | 매개변수가 존재하지 않으면 반환None, 오류가 발생하지 않습니다. |
request.args.get('user') |
request.args.get('key', 'default') |
매개변수 가져오기 및 기본값 제공 | 매개변수가 없으면 지정한 기본값을 반환합니다. | request.args.get('page', 1) |
request.args['key'] |
매개변수에 직접 액세스 | 매개변수가 없으면 오류가 발생합니다.KeyError오류로 인해 500 서버 오류가 발생했습니다. |
request.args['id'] |
request.args.getlist('key') |
동일한 이름을 가진 여러 매개변수 가져오기 | 모든 값을 포함하는 목록을 반환합니다. | request.args.getlist('filter') |
~에서request.args얻은 모든 값은 문자열입니다. 인수가 숫자 또는 부울 값이어야 하는 경우 유형 변환을 수동으로 수행해야 합니다.
# 매개변수 가져오기(문자열)
num_str = request.args.get('num', '0')
#정수로 변환
시도해 보세요:
num_int = 정수(num_str)
ValueError 제외:
num_int = 0 # 변환 실패 처리
# 부울로 변환합니다(참고: 비어 있지 않은 모든 문자열은 Python에서 True입니다).
bool_str = request.args.get('is_admin', 'false').lower()
is_admin = bool_str == '참'
Flask에서 경로를 구별하는 핵심은 Python 코드에서 정의한 함수 이름이 아니라 엔드포인트입니다. 루프와 Python의 클로저(Closure) 기능을 사용하여 경로를 동적으로 정의 및 등록하고 고유한 엔드포인트를 할당할 수 있습니다.
팩토리 함수를 사용하여 각 경로 프로세서를 생성하고 이를 등록할 때 고유한 '엔드포인트' 이름을 지정합니다.
플라스크 가져오기 플라스크, jsonify에서
수입 OS
앱 = 플라스크(__name__)
# 이것이 당신의 데이터 소스라고 가정
Dynamic_apis={
"user_info": {"method": "GET", "handler": 람다: {"data": "사용자 정보를 가져왔습니다"}},
"product_list": {"method": "GET", "handler": 람다: {"data": "제품 목록"}},
"submit_form": {"method": "POST", "handler": 람다: {"data": "양식 제출"}, "methods": ['POST']},
}
filename_base = "db_agent"
# --- 핵심 로직: 라우팅 팩토리 기능 ---
def create_dynamic_route(funstr, handler_func, 메소드):
"""
경로 처리기 함수(클로저)를 만들고 반환합니다.
이 함수는 funstr 및 handler_func의 값을 캡처합니다.
"""
def 동적_route_handler():
# 함수 이름은 고정되어 있지만 funstr은 런타임에 액세스할 수 있습니다.
print(f"요청 처리 중: {funstr}")
# 실제 비즈니스 로직을 실행
결과 = handler_func()
jsonify(결과) 반환
# 생성된 함수를 반환합니다.
Dynamic_route_handler를 반환합니다.
# --- 동적 등록 루프 ---
funstr의 경우, Dynamic_apis.items()의 api_info:
# 1. URL 경로 구축
url_path = f"/{filename_base}/{funstr}"
# 2. 끝점 이름을 정의합니다(고유성을 보장하려면 funstr을 사용하세요).
엔드포인트_이름 = f"{filename_base}_{funstr}_api"
# 3. HTTP 메소드 가져오기
메소드 = api_info.get("methods", ['GET']) # 기본값은 GET입니다.
# 4. 라우팅 처리 기능 생성
handler_func = create_dynamic_route(funstr, api_info["handler"], 메소드)
# 5. 경로 등록
# 함수 이름 대신 고유한 이름을 지정하려면 엔드포인트= 매개변수를 사용하세요.
app.add_url_rule(
URL_경로,
엔드포인트=endpoint_name,
view_func=handler_func,
방법=방법
)
print(f"등록된 경로: {url_path} (엔드포인트: {endpoint_name})")
__name__ == '__main__'인 경우:
# 테스트 엔드포인트(예: http://127.0.0.1:5000/db_agent/user_info)
app.run(디버그=True)
Gradio기계 학습 모델의 접근성과 대화형을 더욱 높이기 위해 설계된 오픈 소스 Python 라이브러리입니다. 간단한 코드를 사용하면 다른 사람이 테스트하고 사용할 수 있는 기계 학습 모델용 웹 인터페이스를 빠르게 구축할 수 있습니다.
Gradio의 사용법은 매우 간단합니다. 다음은 간단한 텍스트 입력 및 출력 인터페이스를 만드는 방법을 보여주는 기본 예입니다.
importgradioasgr
#입력 데이터를 처리하는 함수 정의
데프 인사(이름):
"안녕하세요" + 이름 + "!"를 반환합니다.
# Gradio 인터페이스 생성
iface = gr.Interface(fn=greet, inputs="text", outputs="text")
# 인터페이스 시작
iface.launch()
위의 코드는 사용자가 이름을 입력한 다음 개인화된 인사말을 표시할 수 있는 간단한 웹 인터페이스를 생성합니다.
Gradio는 개발자에게 기계 학습 모델을 웹 애플리케이션으로 신속하게 변환할 수 있는 간단하고 강력한 도구를 제공하여 더 많은 사용자가 AI 결과를 쉽게 테스트하고 경험할 수 있도록 합니다. 개인 프로젝트 또는 팀워크에 사용되는 Gradio는 모델 홍보 및 전시에 이상적입니다.
Gradio 인터페이스의 출력을 Apache HTTP 서버의 페이지(예: `/results`)로 리디렉션하려면 Python의 다음을 사용할 수 있습니다.requestsGradio를 변환하는 모듈
결과는 서버로 전송됩니다. Gradio와 Apache를 통합하는 방법에 대한 기본 단계는 다음과 같습니다.
먼저 Apache HTTP 서버가 실행 중이고 데이터를 처리할 수 있는 엔드포인트가 구성되어 있는지 확인하세요(예:/results). 이 엔드포인트는 PHP, Python 또는 수신 데이터를 처리하는 다른 백엔드 언어일 수 있습니다.
다음은 Gradio 애플리케이션을 작성하고 해당 출력을 HTTP 서버로 리디렉션하기 위한 샘플 코드입니다.
importgradioasgr
수입요청
# Gradio 입력을 처리하고 HTTP 서버로 리디렉션
def process_and_redirect(input_data):
# 입력 데이터 처리
결과 = f"처리됨: {input_data}"
#Apache HTTP 서버에 HTTP POST 요청을 보내고 처리된 데이터를 전달합니다.
url = 'http://your-apache-server-address/results' # 서버 주소로 교체
페이로드 = {'결과': 결과}
시도해 보세요:
응답 = 요청.포스트(url, 데이터=페이로드)
response.status_code == 200인 경우:
f"{url}로 성공적으로 리디렉션되었습니다."를 반환합니다.
그 외:
f"리디렉션에 실패했습니다. 상태 코드: {response.status_code}"를 반환합니다.
e와 같은 예외를 제외하고:
return f"오류가 발생했습니다: {str(e)}"
# Gradio 인터페이스 생성
iface = gr.인터페이스(
fn=프로세스_및_리디렉션,
입력="텍스트",
출력="텍스트",
title="Gradio를 HTTP 서버로 리디렉션"
)
iface.launch()
Apache 서버는 Gradio 데이터를 수신하기 위한 간단한 PHP 스크립트와 같이 POST 요청을 처리하기 위한 엔드포인트로 구성되어야 합니다.
<?php
// Gradio의 POST 요청을 처리합니다.
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$결과 = $_POST['결과']; // POST 요청에서 'result' 매개변수를 가져옵니다.
echo "Gradio에서 받은 데이터: " . htmlspecialchars($result);
}
?>
이를 통해 Gradio 애플리케이션을 사용하여 출력을 Apache HTTP 서버로 리디렉션하고 서버 측에서 데이터를 처리할 수 있습니다. 이러한 통합을 통해 Gradio의 대화형 기능을 웹 환경에서 더욱 광범위하게 사용할 수 있습니다.
Apache 페이지에 Gradio 인터페이스를 포함하는 가장 쉬운 방법은 다음을 사용하는 것입니다.iframe상표. 설정src속성은 Gradio 서버의 URL입니다.
<!DOCTYPE html>
<html lang="zh">
<머리>
<meta charset="UTF-8">
<title>Apache 인터페이스 내장 Gradio</title>
</머리>
<본문>
임베디드 Gradio 인터페이스
<iframe src="http://your-gradio-server-address:7860" width="100%" height="800px"frameborder="0"></iframe>
</body>
</html>
Apache의 URL을 통해 Gradio 인터페이스에 직접 액세스하려는 경우 역방향 프록시를 구성할 수 있습니다. 이렇게 하면 원래 Gradio URL을 표시할 필요가 없습니다.
mod_proxy그리고mod_proxy_http개조. 다음 지침을 실행하십시오.sudo a2enmod proxy
sudo a2enmod proxy_http
아니면 주석을 해제하세요:
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
/gradio)。<Location "/gradio">
ProxyPass "http://localhost:7860/"
ProxyPassReverse "http://localhost:7860/"
</Location>
sudo systemctl restart apache2
완료되면 사용할 수 있습니다.http://your-apache-server-address/gradioApache 페이지에 Gradio의 인터페이스 콘텐츠를 표시합니다.
Apache에서 활성화되어 있는지 확인하십시오.proxy그리고proxy_http개조. 아직 활성화되지 않은 경우 다음 명령을 실행할 수 있습니다.
sudo a2enmod proxy
sudo a2enmod proxy_http
Gradio 애플리케이션의 Apache 구성 파일(예:/etc/apache2/sites-available/yourdomain.conf), ProxyPass를 구성하려면 다음 설정을 추가하세요.
및 ProxyPassReverse:
<VirtualHost *:80>
서버이름 yourdomain.com
# Gradio 루트 디렉토리가 Gradio 서버를 가리키도록 합니다.
ProxyPass/http://localhost:7860/
ProxyPassReverse/http://localhost:7860/
# 정적 리소스가 정상적으로 프록시될 수 있는지 확인
ProxyPass /static/ http://localhost:7860/static/
ProxyPassReverse /static/ http://localhost:7860/static/
</VirtualHost>
설정을 완료한 후 Apache를 다시 시작하여 변경 사항을 적용합니다.
sudo systemctl restart apache2
이러한 구성은 다음과 같은 Gradio 정적 리소스에 대한 요청을 명시적으로 처리할 수 있습니다.theme.css) 누락된 스타일 문제를 해결해야 합니다. Gradio의 정적 파일 경로가 그렇지 않은 경우/static/, 실제 상황에 따라 경로를 조정하십시오.
그라디오에서 사용 가능gr.DataFramePandas DataFrame 또는 기타 표 형식과 같은 표 형식 데이터를 표시하거나 편집하는 위젯입니다. 여기서는 Gradio 사용법을 설명하겠습니다.
DataFrame 구성 요소는 응용 프로그램에서 대화형 데이터 테이블을 만드는 데 사용됩니다.
Gradio가 아직 설치되지 않은 경우 다음 명령을 사용하여 설치할 수 있습니다.
pip install gradio
gr.DataFrame테이블 데이터 표시Gradio를 사용하여 DataFrame을 표시하는 방법은 다음과 같습니다. Gradio 앱에 표시해야 하는 Pandas DataFrame이 있다고 가정해 보겠습니다.
import gradio as gr
import pandas as pd
#샘플 DataFrame 만들기
data = {'이름': ['앨리스', '밥', '찰리'], '나이': [25, 30, 35], '직업': ['엔지니어', '디자이너', '의사']}
df = pd.DataFrame(data)
# DataFrame을 반환하는 함수를 정의합니다.
def show_dataframe():
return df
#Gradio 인터페이스 생성
인터페이스 = gr.Interface(fn=show_dataframe, 출력=gr.DataFrame(), title="개인 데이터 테이블")
interface.launch()
import gradio as gr: 그라디오 제품군을 소개합니다.data: 샘플 데이터를 생성하는 데 사용되는 사전으로 이름, 나이, 직업의 세 가지 열이 포함되어 있습니다.show_dataframe: 표시할 Pandas DataFrame을 반환하는 함수를 정의합니다.gr.DataFrame(): Gradio 인터페이스에서 테이블 표시를 위한 DataFrame 구성 요소를 만듭니다.interface.launch(): 그라디오 애플리케이션을 시작하세요.gr.DataFrame대화형 편집사용자가 테이블을 편집할 수 있도록 허용하려면 다음을 수행하세요.gr.DataFrame중간 설정editable=True, 사용자가 테이블 데이터를 수정할 수 있도록 허용:
인터페이스 = gr.Interface(fn=show_dataframe, 출력=gr.DataFrame(editable=True), title="편집 가능한 인사 데이터 테이블")
실행된 애플리케이션에는 편집 가능한 테이블이 표시되며 사용자는 웹 페이지에서 직접 데이터를 수정할 수 있습니다.
사용될 수 있다psutilGradio 프로그램의 PID를 찾는 모듈입니다. 먼저, 설치했는지 확인하세요.psutil:
pip install psutil
그런 다음 다음 코드를 사용하여 Gradio 관련 프로그램의 PID를 찾을 수 있습니다.
psutil 가져오기
# 'gradio'가 포함된 프로그램 검색
psutil.process_iter(['pid', 'name', 'cmdline'])의 프로세스에 대해:
' '.join(process.info['cmdline'])에 'gradio'가 있는 경우:
print("Gradio 프로그램 PID를 찾았습니다:", process.info['pid'])
PID를 찾으면 다음을 사용할 수 있습니다.terminate()또는kill()프로그램을 종료하는 방법. 예를 들어:
psutil.process_iter(['pid', 'name', 'cmdline'])의 프로세스에 대해:
' '.join(process.info['cmdline'])에 'gradio'가 있는 경우:
process.kill() # 프로그램을 강제 종료합니다.
print(f"종료된 Gradio 프로그램 PID: {process.info['pid']}")
사용kill()이 메소드는 프로그램을 즉시 종료하므로 프로그램에 진행 중인 중요한 작업이 없는지 확인하십시오. 이 샘플 코드는 일치하는 모든 Gradio 프로그램을 종료합니다.
사용될 수 있다psutil특정 포트에서 수신 대기하는 프로그램을 찾는 모듈입니다. 먼저, 설치되었는지 확인하세요.psutil:
pip install psutil
그런 다음 다음 코드를 사용하여 모니터를 찾을 수 있습니다7860포트의 프로그램 PID입니다.
psutil 가져오기
#검색할 포트 번호를 지정합니다.
target_port = 7860
pid_to_kill = 없음
# 지정된 포트에서 수신 대기하는 프로그램 검색
psutil.net_connections(kind='inet')의 conn에 대해:
conn.laddr.port == target_port 및 conn.status == psutil.CONN_LISTEN인 경우:
pid_to_kill = conn.pid
휴식
pid_to_kill인 경우:
print("리스닝 포트 7860의 프로그램 PID를 찾았습니다:", pid_to_kill)
그 외:
print("리스닝 포트 7860에 대한 프로그램을 찾을 수 없습니다.")
PID를 찾으면 다음을 사용할 수 있습니다.psutil.Process~의kill()프로그램을 강제 종료하는 방법:
pid_to_kill인 경우:
프로세스 = psutil.Process(pid_to_kill)
process.kill() # 프로그램을 강제 종료합니다.
print(f"수신 포트 7860의 프로그램 PID가 종료되었습니다: {pid_to_kill}")
그 외:
print("PID를 찾을 수 없기 때문에 프로그램을 종료할 수 없습니다.")
이 코드는 지정된 포트에서 수신 대기 중인 모든 프로그램을 강제로 종료합니다. 실수로 다른 서비스가 종료되는 것을 방지하려면 해당 포트가 Gradio에서 실제로 사용되는지 확인하세요.
Gradio는 주로 기계 학습 모델을 표시하기 위한 빠르고 사용하기 쉬운 웹 UI를 구축하도록 설계되었습니다. 자체적으로는 이미 웹 서버에서 실행되지만 주요 목적은 기존 RESTful API 엔드포인트가 아닌 인간-컴퓨터 상호 작용 인터페이스를 제공하는 것입니다.
Gradio 애플리케이션에 RESTful API 기능을 포함하려는 경우 가장 권장되는 방법은 Gradio 애플리케이션을 **FastAPI** 또는 **Flask**와 같은 보다 강력한 웹 프레임워크에 포함시키는 것입니다. 이를 통해 하위 경로에 Gradio UI를 마운트하는 동안 기본 프레임워크를 사용하여 API 엔드포인트를 정의할 수 있습니다.
FastAPI는 빠르며 Gradio와 함께 Starlette 프레임워크를 사용하므로 임베딩 프로세스가 매우 원활하게 이루어집니다.
# FastAPI, Uvicorn(서버), Gradio 설치
pip 설치 fastapi uvicorn gradio
Gradio를 사용하게 됩니다..to_app()메소드는 Gradio 인터페이스를 ASGI 애플리케이션으로 변환한 다음 FastAPI를 사용합니다.mount기본 애플리케이션에 마운트하는 기능입니다.
fastapi에서 FastAPI 가져오기
fastapi.responses에서 JSONResponse 가져오기
importgradioasgr
# 1. Gradio 애플리케이션 로직 정의
데프 인사(이름):
return f"안녕하세요, {name}님!"
gr_interface = gr.Interface(fn=greet, inputs="text", outputs="text")
# 2. Gradio 인터페이스를 ASGI 애플리케이션으로 변환
gradio_app = gr_interface.to_app()
# 3. FastAPI 메인 애플리케이션 생성
앱 = FastAPI(
title="Gradio + FastAPI 서버",
Description="API 엔드포인트와 Gradio UI를 모두 제공합니다"
)
# 4. (API SVR) RESTful API 엔드포인트 정의
@app.get("/api/v1/status")
def api_status():
return JSONResponse(content={"status": "API가 작동 중입니다"})
@app.get("/api/v1/model_inference")
def api_inference(data: str):
# 여기서 모델 로직을 호출할 수 있습니다
result = f"처리된 데이터: {data.upper()}"
JSONResponse(content={"result": 결과}) 반환
# 5. (Gradio SVR) /gradio 경로에 Gradio 애플리케이션을 마운트합니다.
# mount() 함수를 사용하면 다른 ASGI 응용 프로그램을 지정된 경로에 마운트할 수 있습니다.
app.mount("/gradio",gradient_app)
# 실행 서버 (파일명이 main.py라고 가정)
# 터미널에서 실행: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Gradio 자체는 추가 웹 프레임워크 없이 URL 매개변수를 통해 Gradio 인터페이스의 기본 기능을 직접 호출할 수 있는 실험적 기능도 제공합니다. 이는 표준 RESTful API는 아니지만 간단한 프로그래밍 방식 액세스를 허용합니다.
그러나 FastAPI/Flask를 사용하여 Gradio를 내장하는 것은 보다 표준화된 API 디자인, 문서 및 인증을 제공하는 보다 표준적이고 유연한 접근 방식입니다.
이는 초보자에게 적합한 가장 일반적인 크롤러 조합이며 정적 웹 페이지를 구문 분석하는 데 사용됩니다.
pip install requests beautifulsoup4
사용 예:
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
print(soup.title.string)
멀티 스레드 및 분산 크롤러를 지원하는 대규모 크롤러 프로젝트에 적합한 강력한 크롤러 프레임워크입니다.
pip install scrapy
사용 예:
scrapy startproject myproject
프로젝트에 크롤러 모듈을 생성하고 크롤링 명령어를 실행합니다.
JavaScript로 렌더링된 콘텐츠 처리와 같은 사용자 작업을 시뮬레이션해야 하는 동적 웹 크롤링에 적합합니다.
pip install selenium
사용 예:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
print(driver.title)
driver.quit()
동적 웹 페이지를 처리하는 또 다른 도구로 Selenium보다 성능이 뛰어나고 여러 브라우저를 지원합니다.
pip install playwright
playwright install
사용 예:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()
Puppeteer의 Python 버전을 기반으로 하며 동적 웹 페이지를 크롤링하도록 특별히 설계되었습니다.
pip install pyppeteer
사용 예:
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto("https://example.com")
print(await page.title())
await browser.close()
import asyncio
asyncio.get_event_loop().run_until_complete(main())
HTTP 요청을 전송하고 비동기 작업을 지원하는 효율적인 도구입니다.
pip install httpx
사용 예:
import httpx
async def fetch():
async with httpx.AsyncClient() as client:
response = await client.get("https://example.com")
print(response.text)
import asyncio
asyncio.run(fetch())
To create a simple web scraper in Python, you can use the requests library to get the page content, and BeautifulSoup to parse the HTML.
Here's an example of a basic web scraper:
import requests
from bs4 import BeautifulSoup
# URL to scrape
url = "https://example.com"
# Send a GET request
response = requests.get(url)
response.raise_for_status() # Check for errors
# Parse the HTML content
soup = BeautifulSoup(response.content, "html.parser")
# Extract specific data (e.g., all the headings)
headings = soup.find_all("h1")
# Print the headings
for heading in headings:
print(heading.text)
Note: You may need to install the libraries with the following commands:
pip install requests
pip install beautifulsoup4
추출할 텍스트
다른 텍스트
bs4에서 가져오기 BeautifulSoup
#HTML 파일
html_content = """
추출할 텍스트
다른 텍스트
"""
# HTML 구문 분석
수프 = BeautifulSoup(html_content, 'html.parser')
# 특정 태그 및 카테고리 찾기
span_tag=soup.find('span', class_='xxxclass')
#텍스트 값 추출
범위_태그인 경우:
print(span_tag.text) #출력: 추출할 텍스트
그 외:
print("일치하는 태그가 없습니다.")
# 일치하는 모든 항목 찾기라벨
span_tags=soup.find_all('span', class_='xxxclass')
#각 라벨의 텍스트 추출
span_tags의 태그에 대해:
인쇄(태그.텍스트)
span_tag = soup.find('span', {'class': 'xxxclass', 'id': 'specific-id'})
2. **정규식을 사용하여 카테고리 일치**:
import re
span_tag = soup.find('span', class_=re.compile(r'^xxx'))
Selenium은 주로 웹 브라우저 작업을 자동화하는 데 사용되는 오픈 소스 도구입니다. Chrome, Firefox, Safari 등을 포함한 여러 브라우저를 지원하며 웹 애플리케이션을 테스트하거나 웹 데이터를 스크랩하는 데 사용할 수 있습니다.
다음은 Selenium을 설치하는 단계와 간단한 Python 사용 예입니다.
# 셀레늄 설치
pip 설치 셀레늄
#샘플코드
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
# 웹드라이버 시작
드라이버 = webdriver.Chrome()
드라이버.get("https://www.example.com")
# 요소를 찾고 작업을 수행합니다.
요소 = 드라이버.find_element(By.TAG_NAME, "h1")
인쇄(요소.텍스트)
# 브라우저를 닫습니다
드라이버.종료()
Selenium과 ChromeDriver가 설치되어 있는지 확인하세요.
pip install selenium
적절한 버전의 Chrome을 다운로드하여 설치하세요.ChromeDriver。
Chrome의 사용자 폴더에는 북마크, 방문 기록, 쿠키 등과 같은 개인 데이터가 포함되어 있습니다. 브라우저를 시작하는 데 사용할 특정 폴더를 지정할 수 있습니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.chrome.service 가져오기 서비스에서
selenium.webdriver.chrome.options에서 가져오기 옵션
#ChromeDriver 경로 지정
chromedriver_path = "/경로/to/chromedriver"
#사용자 폴더 지정
user_data_dir = "/경로/to/your/user/data"
# 크롬 옵션 설정
chrome_options=옵션()
chrome_options.add_argument(f"--user-data-dir={user_data_dir}")
chrome_options.add_argument("--profile-directory=Default") # 또는 기타 하위 폴더 이름
# 브라우저 시작
서비스 = 서비스(chromedriver_path)
드라이버 = webdriver.Chrome(서비스=서비스, 옵션=chrome_options)
# 웹페이지를 엽니다
드라이버.get("https://example.com")
# 프로그램 종료
드라이버.종료()
user_data_dir경로는 유효하고 쓰기 가능한 디렉터리입니다.chrome://version。설치되어 있는지 확인하세요selenium그리고psutil:
pip install selenium psutil
다음 코드는 실행 중인 모든 Chrome을 검사하고 추출합니다.user-data-dir매개변수:
import psutil
import re
def get_all_user_data_dirs():
user_data_dirs = set()
for proc in psutil.process_iter(attrs=['pid', 'name', 'cmdline']):
try:
if proc.info['name'] and 'chrome' in proc.info['name'].lower():
cmdline = ' '.join(proc.info['cmdline'])
match = re.search(r'--user-data-dir=([^\s]+)', cmdline)
if match:
user_data_dirs.add(match.group(1))
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
return list(user_data_dirs)
print(get_all_user_data_dirs())
목표를 찾아라user_data_dir마지막으로 Selenium과 함께 사용할 수 있습니다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
chrome_user_data_dir = "C:\\Users\\YourUser\\AppData\\Local\\Google\\Chrome\\User Data"
options = Options()
options.add_argument(f"--user-data-dir={chrome_user_data_dir}")
service = Service("chromedriver.exe")
driver = webdriver.Chrome(service=service, options=options)
driver.get("https://www.google.com")
~을 통해psutil실행 중인 Chrome 프로세스를 구문 분석하여 모든 항목을 가져옵니다.user-data-dir, 특정 사용user_data_dir브라우저를 시작하십시오.
Chrome 사용자 데이터 디렉터리에서 사용자 이름을 얻으려면 일반적으로 다음 경로에 있는 해당 디렉터리의 파일에 액세스해야 합니다.
C:\Users\[Username]\AppData\Local\Google\Chrome\User Data\(Windows)/Users/[Username]/Library/Application Support/Google/Chrome/(macOS)/home/[Username]/.config/google-chrome/(Linux)이 폴더에는 읽을 수 있는 많은 파일이 포함되어 있습니다.Local State사용자에 대한 기본 정보를 얻기 위한 파일입니다.
Local State파일크롬Local State파일에는 사용자 정보를 얻을 수 있는 몇 가지 기본 사용자 설정이 포함되어 있습니다.
JSON 가져오기
수입 OS
def get_chrome_user_name(user_data_dir):
local_state_path = os.path.join(user_data_dir, '로컬 상태')
# 파일이 존재하는지 확인
그렇지 않은 경우 os.path.exists(local_state_path):
"로컬 상태 파일을 찾을 수 없습니다"를 반환합니다.
open(local_state_path, 'r', 인코딩='utf-8')을 파일로 사용:
local_state = json.load(파일)
# 로컬 상태에서 사용자 정보를 가져옵니다.
user_name = local_state.get('profile', {}).get('name', '알 수 없는 사용자')
user_name 반환
# 예: Chrome 사용자 데이터 디렉터리 경로
user_data_dir = r'C:\Users\YourUserName\AppData\Local\Google\Chrome\사용자 데이터'
인쇄(get_chrome_user_name(user_data_dir))
당신이 읽을 때Local State파일을 JSON으로 구문 분석하면 다음과 같은 많은 정보를 얻을 수 있습니다.
profile: 이름, 사진 등 사용자의 구성 정보가 포함됩니다.last_version: 마지막 Chrome 버전을 표시합니다.is_logged_in: 사용자가 로그인되어 있는지 여부를 표시합니다.대부분의 경우 사용자 이름은profile, 위의 방법으로 추출할 수 있다.
파싱하여Local State파일의 JSON 데이터에서 Chrome 사용자 이름을 쉽게 얻을 수 있습니다.
크롬Local State파일은 사용자에 대한 많은 기본 정보를 저장합니다. 모든 사용자 이름을 추출하려면 파일을 읽고 JSON 콘텐츠를 구문 분석하면 됩니다. 이를 달성하는 방법에 대한 단계는 다음과 같습니다.
Local State보관 및 구문 분석당신은 읽을 수 있습니다Local State파일을 찾은 다음 JSON 형식의 콘텐츠를 구문 분석하여 모든 사용자 데이터를 추출합니다.
JSON 가져오기
수입 OS
def get_all_users(user_data_dir):
local_state_path = os.path.join(user_data_dir, '로컬 상태')
# 파일이 존재하는지 확인
그렇지 않은 경우 os.path.exists(local_state_path):
"로컬 상태 파일을 찾을 수 없습니다"를 반환합니다.
open(local_state_path, 'r', 인코딩='utf-8')을 파일로 사용:
local_state = json.load(파일)
# 로컬 상태에서 모든 사용자 데이터를 가져옵니다.
프로필 = local_state.get('profile', {}).get('info_cache', {})
# 모든 사용자 이름을 가져옵니다
user_names = [profiles.values()의 프로필에 대한 profile.get('name', '알 수 없는 사용자')]
user_names 반환
# 예: Chrome 사용자 데이터 디렉터리 경로
user_data_dir = r'C:\Users\YourUserName\AppData\Local\Google\Chrome\사용자 데이터'
인쇄(get_all_users(user_data_dir))
크롬에서Local State파일에서 사용자 데이터는 일반적으로 다음 위치에 저장됩니다.profile아래에info_cache는 각 사용자의 프로필이 구성 이름으로 입력되는 사전입니다.
Local State파일 구조다음은Local State아카이브 구조의 예:
{
"profile": {
"info_cache": {
"profile1": {
"name": "User1",
"avatar": "path/to/avatar1.jpg"
},
"profile2": {
"name": "User2",
"avatar": "path/to/avatar2.jpg"
}
}
}
}
파싱하여Local State파일을 사용하면 Chrome의 모든 사용자 이름을 얻을 수 있습니다. 이렇게 하면 모든 계정을 쉽게 나열할 수 있습니다.
크롬에서Local State파일에는 각 사용자의 데이터가 포함되어 있습니다.info_cache가운데. 여기에서 사용자 이름과 해당 구성 하위 디렉터리를 추출할 수 있습니다.
Local State보관 및 구문 분석Chrome에서 수행하는 방법은 다음과 같습니다.Local State파일에 있는 모든 사용자의 이름과 해당 하위 디렉터리를 얻는 방법입니다.
JSON 가져오기
수입 OS
def get_users_and_profiles(user_data_dir):
local_state_path = os.path.join(user_data_dir, '로컬 상태')
# 파일이 존재하는지 확인
그렇지 않은 경우 os.path.exists(local_state_path):
"로컬 상태 파일을 찾을 수 없습니다"를 반환합니다.
open(local_state_path, 'r', 인코딩='utf-8')을 파일로 사용:
local_state = json.load(파일)
# 로컬 상태에서 모든 사용자 데이터를 가져옵니다.
프로필 = local_state.get('profile', {}).get('info_cache', {})
# 모든 사용자 이름과 해당 하위 디렉터리를 가져옵니다.
user_info = {}
profile_key의 경우,profiles.items()의 profile_data:
user_name = profile_data.get('name', '알 수 없는 사용자')
profile_sub_dir = os.path.join(user_data_dir, '프로필' + profile_key)
user_info[사용자_이름] = profile_sub_dir
user_info 반환
# 예: Chrome 사용자 데이터 디렉터리 경로
user_data_dir = r'C:\Users\YourUserName\AppData\Local\Google\Chrome\사용자 데이터'
users_and_profiles = get_users_and_profiles(user_data_dir)
user_name의 경우 users_and_profiles.items()의 profile_dir:
print(f"사용자 이름: {user_name}, 하위 디렉터리: {profile_dir}")
존재하다Local State파일, 모든 사용자 데이터는 다음 위치에 있습니다.profile아래에info_cache. 각 사용자는 해당 구성 키(예:profile1, profile2기다리다). 구성된 각 프로필에는 사용자 이름(name) 및 기타 관련 정보.
Local State파일 구조다음은Local State아카이브 구조의 예:
{
"profile": {
"info_cache": {
"Profile 1": {
"name": "User1",
"avatar": "path/to/avatar1.jpg"
},
"Profile 2": {
"name": "User2",
"avatar": "path/to/avatar2.jpg"
}
}
}
}
Profile시작하고 뒤에 숫자가 옵니다(예:Profile 1, Profile 2기다리다).파싱하여Local State파일을 사용하면 모든 사용자의 이름과 해당 구성 하위 디렉터리를 얻을 수 있습니다. 이를 통해 각 사용자의 구성 데이터 위치를 쉽게 찾을 수 있습니다.
Chrome 사용자 데이터 디렉터리에서 Gmail 계정을 얻으려면 Chrome 구성 데이터에서 관련 정보를 추출해야 합니다. 이는 일반적으로 Chrome의 사용자 데이터 파일, 특히 Google 관련 계정 데이터를 구문 분석하여 수행됩니다.
각 Chrome 사용자의 데이터는 일반적으로 자신의 폴더에 있습니다.User Data디렉토리 아래Profile디렉토리 내에서. 사용자가 Google 계정에 로그인한 경우 관련 Gmail 계정 정보를 구성 데이터에서 찾을 수 있습니다.
수입 OS
JSON 가져오기
def get_gmail_from_profile(user_data_dir, profile_name):
profile_dir = os.path.join(user_data_dir, profile_name)
account_file = os.path.join(profile_dir, '웹 데이터')
# 파일이 존재하는지 확인
그렇지 않은 경우 os.path.exists(accounts_file):
"웹 데이터 파일을 찾을 수 없습니다"를 반환합니다.
# 웹 데이터 파일을 읽어보십시오.
시도해 보세요:
open(accounts_file, 'r', 인코딩='utf-8')을 파일로 사용:
web_data = json.load(파일)
# 데이터에서 Gmail 계정 추출
web_data.get('accounts', [])의 행에 대해:
row.get('email', '')에 'gmail'이 있는 경우:
row.get('이메일')을 반환합니다.
"Gmail 계정을 찾을 수 없습니다"를 반환합니다.
e와 같은 예외를 제외하고:
return f"웹 데이터 파일 읽기 오류: {e}"
# 예: Chrome 사용자 데이터 디렉터리 경로
user_data_dir = r'C:\Users\YourUserName\AppData\Local\Google\Chrome\사용자 데이터'
# 프로필 1을 사용한다고 가정합니다.
profile_name = '프로필 1'
인쇄(get_gmail_from_profile(user_data_dir, profile_name))
웹 데이터 파일에는 계정 이름, 비밀번호 및 기타 관련 정보를 포함하여 Chrome의 다양한 로그인 데이터가 포함되어 있습니다. 이 예에서는 다음을 찾습니다.email입력란에 Gmail 편지함이 포함되어 있는지 확인하세요.
다음은 웹 데이터 파일의 부분 구조에 대한 예입니다.
{
"accounts": [
{
"email": "[email protected]",
"password": "encrypted_password_1"
},
{
"email": "[email protected]",
"password": "encrypted_password_2"
}
]
}
email)을 일반적으로 추출할 수 있습니다.Chrome 사용자 프로필을 구문 분석하여Web Data파일을 사용하면 사용자의 Gmail 계정을 쉽게 검색할 수 있습니다. 사용자가 Gmail 계정에 로그인한 경우 해당 이메일이 데이터에 표시됩니다.
常见的网页自动化工具包括 Selenium 과 Playwright. 이러한 도구는 클릭, 텍스트 입력 및 기타 사용자 작업을 시뮬레이션할 수 있습니다.
웹사이트의 모든 하이퍼링크를 얻으려면 BeautifulSoup 또는 Playwright와 같은 도구를 사용하세요(<a href>) 탐색할 페이지 목록을 생성합니다.
Selenium 또는 Playwright로 브라우저를 열고 버튼 클릭, 스크롤, 동적 콘텐츠 트리거 등의 사용자 작업을 시뮬레이션합니다.
최신 웹사이트에는 동적으로 생성된 콘텐츠가 많이 포함되어 있는 경우가 많으며, Playwright 또는 Selenium을 사용하여 JavaScript를 실행하면 페이지가 올바르게 로드되도록 할 수 있습니다.
크롤링된 링크를 기반으로 웹사이트의 모든 페이지를 재귀적으로 방문하고 방문한 페이지를 기록하여 중복을 방지합니다.
각 페이지를 탐색할 때 양식 작성, 정보 제출, 작업 결과 기록 등 일반적인 사용자 동작을 시뮬레이션합니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
#브라우저 초기화
드라이버 = webdriver.Chrome()
# 웹사이트 탐색 시작
드라이버.get("https://example.com")
# 모든 링크를 잡아라
링크 = 드라이버.find_elements(By.TAG_NAME, "a")
링크의 링크:
href = link.get_attribute("href")
print(f"링크 발견: {href}")
# 클릭 시뮬레이션
링크가 있는 경우:
링크[0].클릭()
# 브라우저를 닫습니다
드라이버.종료()
웹사이트 탐색 및 시뮬레이션 시 과도한 서버 부하 발생이나 법률 위반을 방지하기 위해 해당 웹사이트의 이용 약관을 준수하시기 바랍니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
selenium.webdriver.support.ui에서 WebDriverWait 가져오기
selenium.webdriver.support에서 예상_조건을 EC로 가져오기
#WebDriver 초기화
드라이버 = webdriver.Chrome()
#대상 웹사이트 열기
드라이버.get("https://example.com")
# 버튼이 나타날 때까지 기다렸다가 클릭하세요.
대기 = WebDriverWait(드라이버, 10)
버튼 = wait.until(EC.element_to_be_clickable((By.ID, "button_id")))
버튼.클릭()
# 다른 요소가 로드될 때까지 기다립니다.
text_field = wait.until(EC.visibility_of_element_location((By.NAME, "text_field_name")))
text_field.send_keys("테스트 데이터")
# 브라우저를 닫습니다
드라이버.종료()
수입 시간
셀레늄 가져오기 웹 드라이버에서
#WebDriver 초기화
드라이버 = webdriver.Chrome()
#대상 웹사이트 열기
드라이버.get("https://example.com")
time.sleep(3) # 3초 동안 일시 정지
# 버튼 클릭 시뮬레이션
버튼 = 드라이버.find_element(By.ID, "button_id")
버튼.클릭()
시간.수면(3)
# 브라우저를 닫습니다
드라이버.종료()**참고**: `time.sleep`은 공식 테스트에는 권장되지 않으며 디버깅 목적으로만 권장됩니다.셀레늄 가져오기 웹 드라이버에서
#WebDriver 초기화
드라이버 = webdriver.Chrome()
#대상 웹사이트 열기
드라이버.get("https://example.com")
# 직접 확인 후 계속 진행
input("다음 단계로 계속하려면 Enter를 누르세요...")
버튼 = 드라이버.find_element(By.ID, "button_id")
버튼.클릭()
# 계속해서 다른 테스트를 수행합니다.
input("다음 단계로 계속하려면 Enter를 누르세요...")
드라이버.종료()
수입 단위 테스트
셀레늄 가져오기 웹 드라이버에서
클래스 TestExample(unittest.TestCase):
데프 설정(자기):
self.driver = webdriver.Chrome()
def test_step_by_step(self):
드라이버 = self.driver
드라이버.get("https://example.com")
input("페이지를 확인하고 계속하려면 Enter를 누르세요...") # 수동 중단점
버튼 = 드라이버.find_element(By.ID, "button_id")
버튼.클릭()
input("작업 결과를 확인하고 계속하려면 Enter를 누르세요...") # 수동 중단점
데프 TearDown(자체):
self.driver.quit()
__name__ == "__main__"인 경우:
단위테스트.메인()
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
# 셀레늄 초기화
드라이버 = webdriver.Chrome()
drivers.get("타겟 웹페이지 URL")
# 특정 줄로 시작하는 텍스트 검색
target_text = "대상 시작 텍스트"
행 = 드라이버.find_elements(By.CSS_SELECTOR, "테이블 tr")
# 결과 저장
결과_데이터 = []
행의 행의 경우:
셀 = row.find_elements(By.TAG_NAME, "td")
셀 및 셀[0].text.startswith(target_text):
# 피어 뒤에 있는 정보를 가져옵니다.
result_data.append([셀 안의 셀에 대한 cell.text])
드라이버.종료()
# 결과를 HTML로 변환
html_output = "<h2>검색 결과</h2>\n"
i의 경우 열거(result_data, start=1)의 row_data:
html_output += f"<h3>라인 {i}</h3>\n<ul>\n"
row_data의 데이터:
html_output += f" <li>{데이터}</li>\n"
html_output += "</ul>\n"
# 결과 표시
인쇄(html_output)
검색결과
1호선
- 대상 시작 텍스트 1
- 기타 정보1
- 기타 정보 2
2호선
- 타겟 오프닝 텍스트 2
- 기타 정보1
- 기타 정보 2
startswith텍스트가 조건을 충족하는지 확인하는 방법입니다.<h2>그리고<h3>및 순서가 지정되지 않은 목록으로<ul>정보를 정리합니다.<head>그리고<body>: 다른 페이지에 쉽게 삽입할 수 있도록 필요한 HTML 태그만 생성합니다.셀레늄에서는find_elements(By.XPATH, xpath)XPath 선택기를 기반으로 기준과 일치하는 모든 요소를 찾고 목록을 반환하는 데 사용됩니다. 그것은 관련이 있다find_element(By.XPATH, xpath)후자는 일치하는 첫 번째 요소만 반환합니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
# 브라우저 시작
드라이버 = webdriver.Chrome()
# 웹페이지 열기
드라이버.get("https://example.com")
# XPath를 사용하여 기준과 일치하는 모든 요소를 찾습니다.
요소 = 드라이버.find_elements(By.XPATH, "//div[@class='example-class']")
# 발견된 요소를 탐색하고 내용을 출력합니다.
요소의 요소에 대해:
인쇄(요소.텍스트)
# 브라우저를 닫습니다
드라이버.종료()
| XPath 표현식 | 설명하다 |
|---|---|
//tagname |
다음과 같이 지정된 태그가 있는 모든 요소를 선택합니다.//div모두를 대표하다div요소 |
//tagname[@attribute='value'] |
속성 값을 기준으로 요소를 선택하세요.//input[@type='text'] |
//tagname[contains(@attribute, 'value')] |
다음과 같은 특정 텍스트를 포함하는 속성//div[contains(@class, 'header')] |
//tagname[text()='text'] |
다음과 같이 텍스트와 정확히 일치하는 요소를 선택하세요.//버튼[text()='제출'] |
//tagname[contains(text(), 'text')] |
다음과 같은 특정 텍스트가 포함된 요소를 선택하세요.//p[contains(text(), '환영합니다')] |
//*[@id='some-id'] |
특정 ID를 가진 요소 선택 |
(//tagname)[index] |
선택index예를 들어 일치하는 요소(//div)[1]첫 번째 div를 선택하세요. |
다음 HTML 구조를 가정합니다.
<div class="product">제품 A</div>
<div class="product">제품 B</div>
<div class="product">제품 C</div>
다음 Selenium 코드를 사용하여 모든 것을 얻을 수 있습니다.product범주div요소:
elements = driver.find_elements(By.XPATH, "//div[@class='product']")
for element in elements:
print(element.text)
find_elements()반환되는 것은 요소가 하나만 발견된 경우에도 목록입니다.find_element(),그렇지 않으면find_elements()。find_elements(By.XPATH, xpath)이는 웹 페이지에서 여러 요소를 찾는 데 사용할 수 있고 크롤러 및 자동화된 테스트에 적합한 Selenium의 강력하고 유연한 검색 방법입니다.
셀레늄에서는By.LINK_TEXT그리고By.PARTIAL_LINK_TEXT하이퍼링크의 텍스트 내용을 기반으로 요소를 찾는 데 사용됩니다.
By.LINK_TEXT: 전체 링크 텍스트를 기준으로 정확히 일치합니다.By.PARTIAL_LINK_TEXT: 링크 텍스트의 일부를 기반으로 퍼지 매칭을 수행합니다.셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
# 브라우저 시작
드라이버 = webdriver.Chrome()
# 웹페이지 열기
드라이버.get("https://example.com")
# 하이퍼링크를 찾으려면 LINK_TEXT를 사용하세요.
element = drivers.find_element(By.LINK_TEXT, "전체 링크 텍스트")
인쇄(element.get_attribute("href"))
# 하이퍼링크를 찾으려면 PARTIAL_LINK_TEXT를 사용하세요.
element_partial = drivers.find_element(By.PARTIAL_LINK_TEXT, "부분 텍스트")
인쇄(element_partial.get_attribute("href"))
# 브라우저를 닫습니다
드라이버.종료()
<a href="https://example.com/page1">전체 링크 텍스트</a>
<a href="https://example.com/page2">자세히 알아보려면 여기를 클릭하세요</a>
클릭하고 싶다고 가정 해보십시오.<a>전체 링크 텍스트</a>, 다음을 사용할 수 있습니다.
drivers.find_element(By.LINK_TEXT, "전체 링크 텍스트").click()
하이퍼링크가 "자세히 알아보려면 여기를 클릭하세요"이지만 "여기를 클릭하세요"만 알고 있는 경우 다음을 사용할 수 있습니다.
drivers.find_element(By.PARTIAL_LINK_TEXT, "여기를 클릭하세요").click()
By.PARTIAL_LINK_TEXT。By.LINK_TEXT정확한 일치를 위해.<a>라벨 링크.find_elements()목록을 반환하는 반면find_element()첫 번째로 일치하는 요소만 반환됩니다.By.LINK_TEXT완전한 링크를 정확하게 찾는 데 유용합니다.By.PARTIAL_LINK_TEXT보다 유연하며 링크 텍스트의 일부를 일치시키는 데 사용할 수 있습니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.by에서 가져오기
selenium.webdriver.support.ui에서 WebDriverWait 가져오기
selenium.webdriver.support에서 예상_조건을 EC로 가져오기
드라이버 = webdriver.Chrome()
시도해 보세요:
elems = WebDriverWait(드라이버, 10).until(
EC.presence_of_all_elements_location((By.CSS_SELECTOR, ".item"))
)
print("찾은 요소:", len(elems))
제외:
print("10초 이내에 요소를 찾을 수 없습니다.")
요소 = 드라이버.find_elements(By.CSS_SELECTOR, ".item")
요소가 아닌 경우:
print("요소를 찾을 수 없습니다.")
그 외:
print("발견된 요소 수:", len(elems))
# iframe으로 전환하고 다시 검색
iframe = 드라이버.find_element(By.TAG_NAME, "iframe")
드라이버.스위치_to.프레임(iframe)
요소 = 드라이버.find_elements(By.CSS_SELECTOR, ".item")
print("발견:", len(elems))
shadow_host = driver.find_element(By.CSS_SELECTOR, "#shadowHost")
shadow_root = driver.execute_script("return arguments[0].shadowRoot", shadow_host)
elem = shadow_root.find_element(By.CSS_SELECTOR, ".target")
def safe_find_elements(driver, by, selector, timeout=10):
시도해 보세요:
WebDriverWait(드라이버, 시간 초과).until(
EC.presence_of_all_elements_ located((by, selector))
)
제외:
return [] # 반환된 빈 목록을 찾을 수 없습니다.
요소 = safe_find_elements(드라이버, By.CSS_SELECTOR, ".item")
요소인 경우:
print("발견:", len(elems))
그 외:
print("요소를 찾을 수 없습니다.")
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.alert에서 가져오기 경고
드라이버 = webdriver.Chrome()
드라이버.get("URL")
경고 = 경고(운전자)
print(alert.text) # 경고 메시지를 받습니다.
Alert.accept() # 확인을 클릭합니다.
드라이버.종료()
경고 = 경고(운전자)
인쇄(경고.텍스트)
Alert.accept() # 확인을 클릭합니다.
# Alert.dismiss() # 취소하려면 클릭하세요.
경고 = 경고(운전자)
인쇄(경고.텍스트)
Alert.send_keys("테스트 입력") #입력 내용
Alert.accept() # 확인을 클릭합니다.
driver.switch_to.alert경고 상자로 전환합니다.try-except테스트 실패를 방지하려면 예외를 처리하세요.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10).until(EC.alert_is_present())
셀레늄에서는 다음을 사용할 수 있습니다.WebDriverWait경고 상자가 나타나지 않아 발생하는 오류를 방지하기 위해 경고 상자가 있는지 확인합니다.
셀레늄 가져오기 웹 드라이버에서
selenium.webdriver.common.alert에서 가져오기 경고
selenium.webdriver.support.ui에서 WebDriverWait 가져오기
selenium.webdriver.support에서 예상_조건을 EC로 가져오기
드라이버 = webdriver.Chrome()
드라이버.get("URL")
시도해 보세요:
# 경고 상자가 있는지 확인하기 위해 5초 동안 기다립니다.
WebDriverWait(드라이버, 5).until(EC.alert_is_present())
경고 = 경고(운전자)
print("경고 상자 내용:", Alert.text)
Alert.accept() # 확인을 클릭합니다.
제외:
print("경고 상자를 찾을 수 없습니다.")
드라이버.종료()
WebDriverWait피하기 위해 전환하기 전에 경고 상자가 나타나는지 확인하십시오.NoAlertPresentException。try-except경고 상자가 없어 테스트가 실패하는 것을 방지합니다.사용WebDriverWait(driver, 5).until(EC.alert_is_present())JavaScript에 의해 생성된 경고 상자만 감지할 수 있으며 '비밀번호 저장', '웹사이트 알림' 등과 같은 Chrome 시스템 수준 경고 상자는 감지할 수 없습니다.
ChromeOptions시스템 수준 경고 상자를 비활성화합니다.pyautogui또는Win32 API키보드 또는 마우스 작동을 시뮬레이션합니다.다음과 같이 Chrome을 시작할 수 있습니다.ChromeOptions알림 및 기타 시스템 전체 팝업을 닫습니다.
셀레늄 가져오기 웹 드라이버에서
옵션 = webdriver.ChromeOptions()
options.add_argument("--disable-notifications") # 알림 비활성화
options.add_argument("--disable-save-password-bubble") # 비밀번호 저장 프롬프트 비활성화
드라이버 = webdriver.Chrome(옵션=옵션)
드라이버.get("URL")
경고 상자가 나타나면 다음을 사용할 수 있습니다.pyautogui누르기와 같은 키 조작을 시뮬레이션합니다.Enter또는Esc닫으려면.
importpyautogui
수입 시간
time.sleep(3) # 경고 상자가 나타날 때까지 기다립니다.
pyautogui.press("enter") # Enter 키를 누르는 것을 시뮬레이션합니다.
Windows 환경에 있는 경우 다음을 사용할 수 있습니다.pygetwindow그리고pywinauto시스템 수준 팝업을 감지하고 닫습니다.
pygetwindow를 gw로 가져오기
importpywinauto
windows = gw.getWindowsWithTitle("Google Chrome") # Chrome 창 가져오기
Windows에서 승리하려면:
if "system Alert" in win.title.lower(): # 제목에 "system Alert"가 포함되어 있는지 확인합니다.
win.close() # 창을 닫습니다.
ChromeOptions경고 상자를 방지합니다.pyautogui또는Win32 API키보드 또는 창 작업을 시뮬레이션합니다.Shadow DOM은 웹 구성 요소의 일부이며 구성 요소의 내부 구현 세부 사항이 외부 세계를 방해하지 않도록 HTML, CSS 및 JavaScript를 캡슐화하는 데 사용됩니다.
간단히 말해서 "범위를 격리"하는 DOM 구조입니다.
---<맞춤 요소>
#shadow-root (열기)
<button>나를 클릭하세요</button>
</맞춤 요소>
button실제로 Shadow DOM에 존재하며 기존 DOM과 함께 사용할 수 없습니다.document.querySelector("button")나타나다.
element.shadowRootelement.shadowRootnull을 반환하며 액세스할 수 없습니다.const shadowHost = document.querySelector('#host');
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = '<p>Hello from Shadow DOM</p>';
---
// 섀도우 DOM 내부
<div><slot name="title">기본 제목</slot></div>
// 외부 사용
<맞춤 요소>
<span Slot="title">맞춤 제목</span>
</맞춤 요소>
---
js = """
const host = document.querySelector('custom-element');
const shadow = host.shadowRoot;
return shadow.querySelector('button');
"""
button = driver.execute_script(js)
button.click()
---
shadowRoot나중에 다시 검색해 보세요Tor 브라우저는 기본적으로 Firefox ESR과 Tor 네트워크 설정 및 향상된 개인 정보 보호 설정을 더한 것입니다. Selenium은 "Tor 브라우저 GUI를 직접 제어"할 수 없지만Firefox + Tor SOCKS ProxyTor 브라우저와 동일한 익명성 효과를 얻는 방법입니다.
먼저 Tor가 로컬 컴퓨터에서 실행되고 있는지 확인하세요. 기본 SOCKS 프록시는 다음과 같습니다.
127.0.0.1:9050
Tor 브라우저를 사용하는 경우 시작 후 일반적으로 다음과 같습니다.
127.0.0.1:9150
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
options = Options()
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.socks", "127.0.0.1")
options.set_preference("network.proxy.socks_port", 9150)
options.set_preference("network.proxy.socks_remote_dns", True)
service = Service("geckodriver.exe")
driver = webdriver.Firefox(service=service, options=options)
driver.get("https://check.torproject.org")
다음 URL을 입력하면 Tor 사용이 성공을 의미한다는 페이지가 표시됩니다.
https://check.torproject.org
Tor 브라우저에 내장된 Firefox를 사용하려면:
options.binary_location = r"C:\Tor Browser\Browser\firefox.exe"
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
options = Options()
options.binary_location = r"C:\Tor Browser\Browser\firefox.exe"
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.socks", "127.0.0.1")
options.set_preference("network.proxy.socks_port", 9150)
options.set_preference("network.proxy.socks_remote_dns", True)
service = Service("geckodriver.exe")
driver = webdriver.Firefox(service=service, options=options)
driver.get("https://check.torproject.org")
Thunderbird에서 이메일을 추출하려면 Python의 IMAP 프로토콜 라이브러리를 사용할 수 있습니다.imaplib또는 타사 라이브러리imapclient. 먼저, 다음을 확인하세요.
Thunderbird에는 IMAP 프로토콜이 활성화되어 있으며 외부 애플리케이션 연결을 허용합니다.
pip를 사용하여 관련 라이브러리를 설치합니다.
pip install imapclient pyzmail36
다음 코드를 사용하여 이메일 서버에 연결하고 중요한 이메일을 추출하세요.
imap클라이언트 가져오기
Pyzmail에서 PyzMessage 가져오기
# 메일 서버 및 로그인 정보 설정
IMAP_SERVER = 'imap.example.com' # IMAP 서버 주소로 교체
이메일 = '[email protected]'
PASSWORD = '귀하의_비밀번호'
# IMAP 서버에 연결
imapclient.IMAPClient(IMAP_SERVER)를 클라이언트로 사용:
클라이언트.로그인(이메일, 비밀번호)
client.select_folder('INBOX')
# 중요하다고 표시된 메시지 검색
메시지 = client.search(['FLAGGED'])
메시지의 uid:
raw_message = client.fetch([uid], ['BODY[]'])[uid][b'BODY[]']
메시지 = PyzMessage.factory(raw_message)
# 이메일 정보 표시
print(f"제목: {message.get_subject()}")
print(f"보낸 사람: {message.get_address('from')}")
print(f"날짜: {message.get_decoded_header('날짜')}")
위의 코드를 실행하여 중요하다고 표시된 이메일을 성공적으로 추출할 수 있는지 확인하세요. 연결 문제가 있는 경우 서버 설정을 확인하거나 IMAP 프로토콜 계층에서 보다 자세한 디버깅을 수행할 수 있습니다.
이러한 방식으로 Python을 사용하여 Thunderbird에서 중요한 이메일을 성공적으로 추출할 수 있습니다.
다음 지침에 따라 PyAutoGUI를 설치합니다.
pip install pyautogui
PyAutoGUI는 마우스 및 키보드 작동을 시뮬레이션할 수 있는 자동화 도구로 GUI 자동화 테스트 또는 반복 작업에 적합합니다.
마우스 위치 및 동작 제어:
importpyautogui
# 화면 해상도를 얻습니다
screen_width, screen_height = pyautogui.size()
print(f"화면 해상도: {screen_width}x{screen_height}")
# 지정된 좌표로 마우스를 이동합니다.
pyautogui.moveTo(100, 100, 기간=1)
# 현재 위치에서 마우스를 움직인다
pyautogui.move(50, 50, 기간=1)
# 마우스 클릭 시뮬레이션
pyautogui.click(200, 200)
# 마우스 오른쪽 버튼 클릭 시뮬레이션
pyautogui.rightClick()
# 드래그 동작 시뮬레이션
pyautogui.dragTo(400, 400, 기간=1)
키보드 키 입력 시뮬레이션:
importpyautogui
# 텍스트를 입력하세요
pyautogui.write("안녕하세요, PyAutoGUI!", 간격=0.1)
# 특정 키를 누르는 것을 시뮬레이션합니다.
pyautogui.press("입력")
# 여러 키를 동시에 누르세요
pyautogui.hotkey("ctrl", "c") # 텍스트 복사
스크린샷을 찍거나 특정 이미지를 찾으세요.
importpyautogui
# 전체 화면을 캡처
스크린샷 = pyautogui.screenshot()
스크린샷.저장("스크린샷.png")
# 화면에서 이미지 찾기
위치 = pyautogui.locateOnScreen("image.png")
위치:
print(f"이미지 위치: {location}")
그 외:
print("이미지를 찾을 수 없습니다.")
프로그램이 무기한 실행되는 것을 방지하려면 다음을 사용할 수 있습니다.pyautogui.FAILSAFE:
pyautogui.FAILSAFE = True # 기본값은 True입니다.
# 마우스를 화면 왼쪽 상단(0, 0)으로 이동하면 프로그램이 즉시 종료됩니다.
Surfshark VPN이 다음과 같은 명령줄 도구를 제공하지 않는 경우surfshark-cli), GUI 자동화 도구(예:pyautogui) 수동 조작을 시뮬레이션합니다.
pyautogui모듈(다음을 통해 사용 가능pip install pyautogui설치하다).~을 통해pyautoguiSurfshark의 그래픽 인터페이스에서 버튼 클릭을 자동화하여 VPN에 연결하거나 연결을 끊습니다.
다음 예에서는 Surfshark VPN에 고정된 버튼 위치가 있고 다음을 사용한다고 가정합니다.pyautogui해야 할 일:
importpyautogui
수입 시간
def connect_vpn():
# Surfshark가 켜져 있는지 확인하세요
print("VPN에 연결해 보세요...")
# "연결" 버튼 클릭을 시뮬레이션하고 실제 위치에 따라 좌표를 조정합니다.
pyautogui.click(x=500, y=300) # "Connect" 버튼의 위치로 교체
time.sleep(5) # 연결이 완료될 때까지 기다립니다.
print("VPN 연결됨")
def 연결 해제_vpn():
# Surfshark가 켜져 있는지 확인하세요
print("VPN 연결을 끊어보세요...")
# "연결 끊기" 버튼 클릭을 시뮬레이션하고 실제 위치에 따라 좌표를 조정합니다.
pyautogui.click(x=500, y=350) # "연결 끊기" 버튼의 위치로 교체
time.sleep(5) # 연결 해제가 완료될 때까지 기다립니다.
print("VPN 연결이 끊어졌습니다.")
# 테스트
연결_VPN()
연결 해제_vpn()
x그리고y좌표.subprocess예를 들어 응용 프로그램을 엽니다.subprocess.run("start surfshark.exe", shell=True)。좌표 방법이 불안정한 경우 이미지 인식(예:pyautogui.locateOnScreen()) 버튼 위치를 찾아 유연성을 높입니다.
Kivy는 멀티터치 애플리케이션의 신속한 개발을 위한 오픈 소스 Python 프레임워크입니다. 개발자가 Windows, macOS, Linux, iOS 및 Android에서 작업할 수 있도록 크로스 플랫폼 지원을 염두에 두고 설계되었습니다. 동일한 코드가 여러 플랫폼에서 실행될 때까지 기다립니다. Kivy는 휴대폰, 태블릿, 데스크톱 장치용 GUI 애플리케이션을 구축하는 데 특히 적합하며 멀티 터치 지원이 뛰어납니다.
Kivy 애플리케이션은 코드나 Kivy의 독점 언어 KV 파일을 통해 배치할 수 있는 여러 위젯으로 구성됩니다. 다음은 클릭하면 색상이 변경되는 버튼을 표시하는 간단한 애플리케이션 예제입니다.
kivy.app에서 앱 가져오기
kivy.uix.button에서 가져오기 버튼
클래스 MyApp(앱):
데프 빌드(자체):
return Button(text='안녕하세요, 키비!',
background_color=(0, 1, 0, 1)) # 녹색 버튼
__name__ == '__main__'인 경우:
마이앱().run()
Kivy는 pip를 통해 설치할 수 있습니다.
pip install kivy
Kivy는 다음을 포함하되 이에 국한되지 않는 다양한 애플리케이션 시나리오에 적합합니다.
Kivy는 크로스 플랫폼 애플리케이션을 구축하기 위한 Python 프레임워크이지만 일반적으로 로컬 장치에서 실행됩니다. Kivy 애플리케이션을 원격으로 표시하려면 다음 옵션을 고려할 수 있습니다.
VNC(가상 네트워크 컴퓨팅) 또는 기타 원격 데스크톱 도구(예: RDP, TeamViewer 등)를 사용하여 Kivy 애플리케이션을 원격으로 제어하고 표시할 수 있습니다.
Linux를 사용하는 경우 X11 전달을 사용하여 원격으로 그래픽 인터페이스를 표시할 수 있습니다.
ssh -X username@remote_host
Flask 또는 기타 웹 프레임워크를 사용하여 Kivy 애플리케이션의 일부를 원격 사용자에게 노출하고 웹 브라우저를 사용하여 표시할 수 있습니다.
컨테이너화된 환경에서 Kivy 앱을 실행하려면 Docker 및 VNC를 사용하여 설정할 수 있습니다.
This error indicates that the tickmarker module from Kivy's Garden is not installed. To fix this issue, follow the steps below:
pip install kivy-garden
garden install tickmarker
Once you've done these steps, try running your Kivy application again.
Rio UI는 Python을 핵심으로 하는 사용자 인터페이스 프레임워크로, 개발자가 간단하고 직관적인 방식으로 대화형 애플리케이션을 작성할 수 있도록 설계되었습니다. Python 프로그래밍 논리를 기반으로 하며 최신 프런트 엔드 기술을 통해 UI를 제공합니다.
pip install rio-ui
import rio
app = rio.App()
@app.page("/")
def index():
return rio.Text("Hello, Rio UI with Python!")
if __name__ == "__main__":
app.run()
email: [email protected]