함수 정의
함수는 def 키워드로 정의합니다.
반복적으로 사용하는 코드를 묶어두면 재사용성이 높아지고 코드를 이해하기 쉬워집니다.
def 함수이름(매개변수):
# 실행할 코드
return 반환값
def calc_gc(seq):
g = seq.count("G")
c = seq.count("C")
return (g + c) / len(seq)
result = calc_gc("ATCGATCGGGCC")
print(result) # 0.5833...
return이 없거나 return만 단독으로 사용하면 None을 반환합니다.
def print_info(sample_id):
print(f"Processing: {sample_id}")
# return 없음 → None 반환
result = print_info("sample_01")
print(result) # None
인자의 종류
위치 인자 (positional argument)
함수 호출 시 순서대로 전달하는 기본 인자입니다.
def describe_sample(sample_id, species, coverage):
print(f"{sample_id} | {species} | {coverage}x")
describe_sample("sample_01", "Homo sapiens", 30.5)
기본값 인자 (default argument)
매개변수에 기본값을 지정하면 호출 시 해당 인자를 생략할 수 있습니다.
def filter_reads(seq, min_length=50, min_quality=20):
if len(seq) >= min_length:
return True
return False
filter_reads("ATCG" * 20) # 기본값 사용
filter_reads("ATCG" * 20, min_length=100) # min_length만 변경
filter_reads("ATCG" * 20, 100, 30) # 순서대로 전달
기본값이 있는 매개변수는 반드시 기본값이 없는 매개변수 뒤에 위치해야 합니다.
def func(a, b=10, c=20): # 올바름
pass
def func(a=10, b): # SyntaxError
pass
기본값으로 가변 객체를 사용하면 안 됩니다.
기본값은 함수가 정의될 때 한 번만 생성되므로, 가변 객체(리스트, 딕셔너리)를 기본값으로 사용하면 호출 간에 상태가 공유되는 문제가 생깁니다.
# 잘못된 예
def add_gene(gene, gene_list=[]):
gene_list.append(gene)
return gene_list
print(add_gene("TP53")) # ['TP53']
print(add_gene("BRCA1")) # ['TP53', 'BRCA1'] ← 이전 호출 결과가 남아있음
# 올바른 예
def add_gene(gene, gene_list=None):
if gene_list is None:
gene_list = []
gene_list.append(gene)
return gene_list
키워드 인자 (keyword argument)
호출 시 매개변수 이름을 명시해서 순서에 관계없이 전달할 수 있습니다.
def describe_sample(sample_id, species, coverage):
print(f"{sample_id} | {species} | {coverage}x")
describe_sample(coverage=30.5, sample_id="sample_01", species="Homo sapiens")
위치 인자와 키워드 인자를 혼합할 때는 위치 인자가 반드시 앞에 와야 합니다.
describe_sample("sample_01", coverage=30.5, species="Homo sapiens") # 올바름
describe_sample(sample_id="sample_01", "Homo sapiens", 30.5) # SyntaxError
*args
매개변수 앞에 *를 붙이면 위치 인자를 개수에 관계없이 튜플로 받습니다.
def sum_values(*args):
print(type(args)) # <class 'tuple'>
return sum(args)
print(sum_values(1, 2, 3)) # 6
print(sum_values(10, 20, 30, 40)) # 100
일반 매개변수와 함께 사용할 수 있습니다.
*args는 일반 매개변수 뒤에 위치합니다.
def process_samples(method, *samples):
for sample in samples:
print(f"[{method}] {sample}")
process_samples("QC", "sample_01", "sample_02", "sample_03")
# [QC] sample_01
# [QC] sample_02
# [QC] sample_03
리스트나 튜플을 *로 언패킹해서 전달할 수도 있습니다.
samples = ["sample_01", "sample_02", "sample_03"]
process_samples("QC", *samples) # 리스트를 언패킹해서 전달
**kwargs
매개변수 앞에 **를 붙이면 키워드 인자를 개수에 관계없이 딕셔너리로 받습니다.
def print_metadata(**kwargs):
print(type(kwargs)) # <class 'dict'>
for key, value in kwargs.items():
print(f"{key}: {value}")
print_metadata(sample_id="sample_01", species="Homo sapiens", coverage=30.5)
# sample_id: sample_01
# species: Homo sapiens
# coverage: 30.5
일반 매개변수, *args와 함께 사용할 수 있습니다.
순서는 반드시 일반 인자 → *args → **kwargs여야 합니다.
def log(level, *messages, **metadata):
print(f"[{level}]", " ".join(messages))
for k, v in metadata.items():
print(f" {k}: {v}")
log("INFO", "Processing", "sample_01", tool="fastp", version="0.23")
# [INFO] Processing sample_01
# tool: fastp
# version: 0.23
딕셔너리를 **로 언패킹해서 전달할 수 있습니다.
params = {"min_length": 50, "min_quality": 20}
filter_reads("ATCGATCG" * 10, **params)
키워드 전용 인자 (keyword-only argument)
* 뒤에 오는 매개변수는 반드시 키워드 인자로만 전달할 수 있습니다.
함수 호출 시 인자의 의미를 명확하게 하고 싶을 때 사용합니다.
def align(query, reference, *, min_identity=0.9, threads=4):
pass
align("seq.fa", "ref.fa", min_identity=0.95, threads=8) # 올바름
align("seq.fa", "ref.fa", 0.95, 8) # TypeError
* 뒤의 min_identity와 threads는 위치 인자로 전달하면 오류가 발생합니다.
반환값
함수는 여러 값을 튜플로 반환할 수 있습니다.
def get_sequence_stats(seq):
length = len(seq)
gc = (seq.count("G") + seq.count("C")) / length
at = 1 - gc
return length, gc, at # 튜플로 반환
length, gc, at = get_sequence_stats("ATCGATCGGGCC")
print(f"Length: {length}, GC: {gc:.2%}, AT: {at:.2%}")
조건에 따라 다른 타입을 반환하는 함수는 처리하기 까다로울 수 있습니다.
반환 타입을 일관되게 유지하는 것이 좋습니다.
함수 인자 전달 방식
파이썬은 객체의 참조를 전달합니다.
불변 객체(숫자, 문자열, 튜플)는 함수 안에서 변경해도 원본에 영향을 주지 않지만, 가변 객체(리스트, 딕셔너리)는 함수 안에서 변경하면 원본도 바뀝니다.
def modify(lst):
lst.append(99)
data = [1, 2, 3]
modify(data)
print(data) # [1, 2, 3, 99] ← 원본이 변경됨
원본을 변경하지 않으려면 복사본을 전달합니다.
modify(data.copy())
modify(data[:])
인자 종류 정리표
| 종류 | 형태 | 설명 |
| 위치 인자 | def f(a, b) | 순서대로 전달 |
| 기본값 인자 | def f(a, b=10) | 생략 시 기본값 사용 |
| 키워드 인자 | f(a=1, b=2) | 이름으로 전달, 순서 무관 |
| *args | def f(*args) | 가변 위치 인자, 튜플로 수신 |
| **kwargs | def f(**kwargs) | 가변 키워드 인자, 딕셔너리로 수신 |
| 키워드 전용 | def f(*, key) | 반드시 키워드로만 전달 |
'BI&Programming-Tools > Python' 카테고리의 다른 글
| [파이썬 기초] 변수 범위와 파일 읽기·쓰기 (0) | 2026.06.17 |
|---|---|
| [파이썬 기초] 정규표현식 (re 모듈) (0) | 2026.06.17 |
| [파이썬 기초] 람다 함수와 내장 함수, collections 모듈 (0) | 2026.06.16 |
| [파이썬 기초] 반복문 (while, for, comprehension) (0) | 2026.06.16 |
| [파이썬 기초] 조건문과 연산자 (0) | 2026.06.15 |
