남용해서는 안 되는 전역 변수지만 가끔 함수 내에서 값을 변경해야할 때가 있다. 그럴 때 파이썬에서는 global 키워드를 이용해 이 변수가 전역변수라는 표시를 해준다.
test = 456
def test1():
test = 123
print(test) #123
def test2():
print(test) #456
위의 함수는 수정할 때에 global 키워드를 넣어주지 않았기 때문에 test1의 test가 지역변수로 간주되어 test2 에서의 test 값에는 반영되지 않았다.
test = 456
def test1():
global test = 123
print(test) #123
def test2():
print(test) #123
global 키워드를 넣어 전역 변수라는 표시를 한 결과 제대로 전역 변수의 값이 바뀐 것을 확인할 수 있다.
변수의 자료형type을 알려주는 함수이다. 특히 숫자가 어떤 형태인지 - 같은 1이라도 1인지 "1"인지 1.00인지에 따라 써줘야 하는 함수 등이 달라진다 - 알아내야 할 때 자주 쓰인다.
구분자를 기준으로 문자열을 나눠준다.
string = "hello/python/world"
string_list = string.split("/") #['hello', 'python', 'world']
이런 식으로 쓴다.
문자열을 합쳐준다. "사이에 들어갈 문자".join(리스트)
형식으로 쓴다.
string_list = ['hello', 'python', 'world']
string = " ".join(string_list) #"hello python world" 공백을 사이에 넣어줌
조건문에는 비교 연산자나 boolean 연산자 등 다양한 연산자를 이용해 조건에 맞을 시 실행될 로직을 정할 수 있다.
print(bool(""))
print(bool(0))
print(bool([]))
print(bool("sample"))
print(bool([1, 2]))
print(bool(1))
print(bool(-1)) # 0이 아닌 숫자는 True로 판단
# sample result
"""
False
False
False
True
True
True
True
"""
함수에는 리턴 타입이 존재하고, 함수를 사용할 때에는 당연하게도 각 함수의 리턴 타입을 고려하여 활용해야 에러가 나지 않는다. typeerror를 계속 보다보면 알아서 적응하게 된다
sort와 sorted는 모두 list를 정렬해주는 메소드지만 둘의 사용방법과 리턴타입은 다르다.
# sort
sample_list = [3, 2, 4, 1, 5]
sample_list.sort() # return data 없이 list 자체를 정렬
print(sample_list) # [1, 2, 3, 4, 5]
# sorted
sample_list = [3, 2, 4, 1, 5]
sorted_list = sorted(sample_list) # 정렬 된 list를 return
내가 사용하는 함수의 리턴타입이 헷갈릴 때는 구글에 검색해 사용 방법의 예시를 보거나 타입에러를 직접 마주해보자.
try~exception, java에서도 지원하는 기능이다. 파이썬에서도 try: except: 문을 통해 예외처리를 해 보다 완성도 높은 결과를 낼 수 있다.
number = "num"
try: # try 구문 안에서 에러가 발생할 경우 except로 넘어감
number = int(number) # "num"은 숫자로 변환할 수 있는 타입이 아님
except: # 에러가 발생했을 때 처리
print(f"{number}은(는) 숫자가 아닙니다.")
변수를 묶거나 푸어주는 것을 말한다. 딕셔나리 형태나 리스트 형태의 값을 함수에 넣어줄 때 주로 사용한다.
def set_profile(**kwargs): #kwargs를 이용해서 딕셔너리 형태로 값을 받아준다
profile = {} #딕셔너리 선언
profile["name"] = kwargs.get("name", "-")
profile["gender"] = kwargs.get("gender", "-")
profile["birthday"] = kwargs.get("birthday", "-")
profile["age"] = kwargs.get("age", "-")
profile["phone"] = kwargs.get("phone", "-")
profile["email"] = kwargs.get("email", "-")
# name, gender, birthday 등의 value를 - 를 디폴트값으로 해서 받는다
return profile
user_profile = {
"name": "lee",
"gender": "man",
"age": 32,
"birthday": "01/01",
"email": "python@sparta.com",
}
# 프로필을 하나 만들어주고
# user_profile을 받아서 출력해준다
print(set_profile(**user_profile))
""" 아래 코드와 동일
profile = set_profile(
name="lee",
gender="man",
age=32,
birthday="01/01",
email="python@sparta.com",
)
"""
# result print
"""
{
'name': 'lee',
'gender': 'man',
'birthday': '01/01',
'age': 32,
'phone': '-',
'email': 'python@sparta.com'
}
"""
# *args로 리스트를 받아서 그 값을 모두 더해준다
def add(*args):
result = 0
for i in args:
result += i
return result
numbers = [1, 2, 3, 4]
# numbers에 리스트를 받아 함수에 넣어준다
print(add(*numbers))
""" 아래 코드와 동일
print(add(1, 2, 3, 4))
"""
# 1 + 2 + 3 + 4 = 10
# result output
"""
10
"""
*args 와 **kwargs
https://brunch.co.kr/@princox/180
파이썬의 클래스 또한 자바와 크게 다르지 않다.
__init__(self, 원하는변수)
가 생성자이다.
ex)
# class에 __init__메소드를 사용할 경우 인스턴스 생성 시 해당 메소드가 실행된다.
class CookieFrame():
def __init__(self, name):
print(f"생성 된 과자의 이름은 {name} 입니다!")
self.name = name
cookie1 = CookieFrame("cookie1") # 생성 된 과자의 이름은 cookie1 입니다!
cookie2 = CookieFrame("cookie2") # 생성 된 과자의 이름은 cookie2 입니다!
객체를 아우를 수 있는 상위 클래스를 만든 뒤 이 클래스를 상속받는 하위 클래스를 여러 개 만들어서 공통적인 부분을 오버라이딩/오버로딩 하여 쓸 수 있다.
# 불속성/빙속성 몬스터의 종을 아우르는 몬스터 클래스를 만든 뒤 공통적인 속성 - hp를 넣어준다
class Monster():
def __init__(self, hp):
self.hp = hp
def attack(self, damage):
self.hp -= damage
def status_check(self):
print(f"monster's hp : {self.hp}")
# Monster 클래스를 상속받는 화속성 몬스터 클래스
class FireMonster(Monster):
#생성자 오버라이딩
def __init__(self, hp):
# 본인 클래스의 속성
self.attribute = "fire"
# super()을 이용해서 Monster 클래스의 __init__부분 재사용
super().__init__(hp)
# 부모 클래스에 존재하는 status_check 메소드를 overriding 합니다.
def status_check(self):
print(f"fire monster's hp : {self.hp}")
class IceMonster(Monster):
def __init__(self, hp):
self.attribute = "ice"
super().__init__(hp)
def status_check(self):
print(f"ice monster's hp : {self.hp}")
fire_monster = FireMonster(hp=100)
# FireMonster 클래스에는 attack 메소드가 없지만
# 부모 클래스에서 상속받았기 때문에 별도의 선언 없이 사용 가능
fire_monster.attack(20)
fire_monster.status_check()
ice_monster = IceMonster(hp=200)
ice_monster.attack(50)
ice_monster.status_check()
이처럼 상속을 하면 공통된 부분에 필요한 부분을 더하여 새로운 클래스를 만들 수 있을 뿐 아니라 같은 선언부의 메서드에 구현부만 다르게 해여 메서드를 다양하게 응용할 수 있다.
난 객체 지향 언어를 자바 외에는 다뤄보지 않아서 파이썬도 당연히 객체 선언을 한 뒤 사용해야 하는 줄 알았는데 그냥 메인부에서 클래스이름.메서드() 로 사용하길래 조금 놀랐던 기억이 있다.
정규표현식은 파이썬 뿐이 아니라 리눅스 문법에서도 종종 사용되는 편리한 도구이다. 몇 개의 기호로 긴 조건을 간단하게 표현할 수 있다.
다만 정규표현식을 이용해 원하는 바를 정확히 표현하기는 굉장히 어렵기 때문에 미리 만들어져있는 정규표현식을 가져다 사용하는 것도 좋은 방법이다.
ex) 유효한 이메일인지 검증하기
from pprint import pprint
import re
# re모듈을 이용해 정규표현식과 맞는지 검사
# rstring : backslash(\)를 문자 그대로 표현
# ^[\w\.-]+@([\w-]+\.)+[\w-]{2,4}$ : 이메일 검증을 위한 정규표현식 코드
email_regex = re.compile(r"^[\w\.-]+@([\w-]+\.)+[\w-]{2,4}$")
def verify_email(email):
return bool(email_regex.fullmatch(email))
test_case = [
"apple", # False
"sparta@regex", # False
"$parta@regex.com", # False
"sparta@re&ex.com", # False
"spar_-ta@regex.com", # True
"sparta@regex.co.kr", # True
"sparta@regex.c", # False
"sparta@regex.cooom", # False
"@regex.com", # False
]
result = [{x: verify_email(x)} for x in test_case]
pprint(result)
많은 도움이 되었습니다, 감사합니다.