JS를 기본으로 python이 가진 특성에 대해 정리해보았다. 전에 python을 이용해서 pandas와 graph 패키지를 통해 CSV를 가공한 경험이 있는지라 바닥부터 배우기에는 시간이 아까워서 JS와 다른 점만 정리했다.
* 데이터형과 타입, 연산자
js
typeof("asdf")
typeof "asdf"
python
type("asdf")
- None 타입의 존재. JS의 null과 비슷함. python에만 존재
- 불린값이 True, False로 앞 글자가 대문자다. JS는 true, false로 소문자이다.
- JS는 number로 퉁치지만 python에는 int와 float으로 나뉜다.
(JS에서 NaN을 number로 친다는 건 비밀이다.)
- JS는 &&와 || 을 사용하지만 python은 and와 or을 사용
* [list]
mutable 즉, 변경이 가능함. append와 같이 단순히 값을 추가하는 것부터 복잡한 연산을 통해 원본을 변형하는 것이 가능함. JS에서 다뤄봐서 알겠지만 어떤 경우는 원본 변경이 불가한 경우가 있었다. (얕은 복사)
a = [1, True, "Test"]
b = [1, 3, 5]
# type은 list
print(type(a))
# 원소 포함 여부 체크
# 이건 JS에서도 지원
print(1 in a)
print(1 not in a)
# destructuring을 할 필요가 없다.
# JS에서는 const newArray = [...a, ...b] 따위를 했을 것.
print(a + b)
# index 0부터 2까지 출력
print(a[0:3])
# JS에서는 a.length
print(len(a))
# 최대, 최소값
print(max(b), min(b))
# 그 밖의 메서드들
b.append(9)
b.reverse()
b.clear()
* (tuple)
list와 달리 immutable함.
a = 3,
b = (1, 3, 7)
print(type(a))
print(3 in a)
print(1 not in a)
* {dictionary}
js의 object와 비슷하다.
a = {"first": 1,
"lunch": "hamberger",
"item": ["knife", 5],
"obj": {"number": 1, "bool": True}
}
# 요소 추가 가능
a["who"] = "me"
print(a)
JS와 비교해보면 python은 키값을 문자열로 명시해줘야 한다는 것이다. 꺼내 쓸 때도 ""로 꺼내야 한다.
물론 JS도 key값으로 올 수 있는 건 String과 Number(js에선 배열이란 key를 숫자로 가진 objectd이므로) 이고, 문자열로 처리되지만 직접적으로 ""로 매겨주지는 않았다. 하지만 "" 로 매겨줘야 한다.
const a = {first: 1, lunch: "ham", item: ["knives", 5], obj: {bool : true}}
* built-in function
# 문자열이나 배열의 길이
print(len([1, 3, 5]))
print(len("whatthehell"))
# eval. 가급적 쓰지 말자
print(eval("1+3"))
# 타입 변경
a = "5"
b = 5
print(type(int(a)))
print(type(str(b)))
* defining function / 템플릿 문자열 f"{var}..."
JS와 미묘하게 같은 점이 많다.
- JS
`hello I'm ${name}`
-Python
f"hello I'm {name}"
- JS
const test = (a=3) => console.log(a)
- Python
def test(a=3):
print(a)
closure
def sum(a, b):
return a + b
def addTwo(num):
a = 2
return sum(a, num)
print(addTwo(100))
# 함수 기본
def test():
print("test")
print("test2")
test()
# 함수 인자와 기본값 지정
def say_name(name="anonymous"):
print(f"hello. I'm {name}")
say_name()
# return
def plus(a, b=3):
return a + b
print(plus(plus(3), -7))
# keyboard argument
# 함수의 인자값을 지정하여 실수를 줄일 수 있다...만 귀찮다.
def introduce(name, lunch):
return f"Hello. I'm {name}. I ate {lunch}."
print(introduce(name="Darren", lunch="soup"))
print(introduce("Darren", "soup"))
* if / elif/ else
else if가 아니라 elif를 쓴다.
# if/else
def plus(a, b):
if (type(a) is int and type(b) is int):
return a + b
else:
return None
plus('d', 3)
# if/elif/else
def drink(age):
if (age > 18):
return ("already drunken")
elif (age > 15):
return ("Nope!")
else:
return ("you cool as hell")
print(drink(24))
print(drink(17))
print(drink(3))
* for in
JS에서는 for..in, for..of 구문을 사용했다.
사실 JS에서는 배열을 만나면 map, filter, reduce를 더 많이 사용하기 때문에 for문을 잘 돌릴 기회가 없다.
하여튼 python도 이와 비슷하지만 더 간단하다.
# 배열에서 for문 사용 빈도가 가장 높다
for i in range(0, 5):
if (i % 2 is 0):
print("even")
else:
print("odd")
# 문자열도 가능
for i in "what":
print(i)
# 튜플도 가능
for i in (1, 3, 5):
print(i)
* 모듈
JS에서는 npm, yarn을 통해 모듈을 설치한 후 import해서 사용했지만 파이썬은 기본적으로 가지고 있는 모듈이 있다.
임포트 하는 방식이 JS(import .... from ...)과 정반대라서 (from ... import ....) 자주 헷갈린다.
-Js
import express from "express"
const express = require("express")
-python
import math : math 모듈의 전체를 import 하게 된다.
from math import ceil, fabs, fsum : math 모듈의 일부만 import 하게 된다.
주의할 점은, import하는 방식이 달라지면 사용하는 방식도 달라진다는 것이다. 전체를 임포트하게 되면 앞에 모듈을 명시해야 하며 개별적으로 임포트한 경우는 임포트한 것을 바로 사용해야 한다.
# 전체 import
import math
print(math.ceil(1.2))
print(math.fabs(-1.2))
print(math.fsum([1, 3, 5]))
# 모듈의 일부만 import
from math import ceil, fabs, fsum as floatsum
print(ceil(1.2))
print(fabs(-1.2))
print(floatsum([1, 3, 5]))
* export 없는 import
js에서는 export를 한 뒤에 해당 파일을 import하여 사용했지만 python에서는 export 없이 import합니다. import하고 싶은 기능이 있는 파일을 모듈 처럼 가져오시면 됩니다.
// cal.py
def plus(a, b):
return a + b
// playground.py
from cal import plus
print(plus(3, 4)) // output: 7
* 패키지 관리 시스템
node 환경에서는 npm 혹은 yarn을 통해서 패키지를 설치하지만 python에서는 pip을 사용합니다.
// requests 설치
pip install requests
// requests 패키지에 대한 정보 출력
pip show requests
// requests 제거
pip uninstall requests
// 설치된 패키지 출력
pip list
에러 핸들링을 위한 try/except
- py : try/except/finally
return 하는 거에 신경써주자
def again():
try:
selected_index = int(input("# :"))
if (selected_index >= len(countrys)):
print("Choose a number from the list")
return again()
return selected_index
except ValueError:
print("That wasn't a number")
return again()
- js : try/catch/finally
import axios frmo axios
...(중략)
try {
const {movies: {title}} = axios.get(`어쩌구 저쩌구 엔드 포인트`)
console.log(title)
} catch(e) {
console.log(e)
} finally {
console.log('asdf')
}
python의 고유 문법들
리스트 Comprehension(함축)
외에도 딕셔너리, 셋, 튜플 컴프리헨션이 존재하나, 대개 딕셔너리, 리스트 컴프리헨션을 사용한다.
아래 예시에서 주의할 점은 조건은 병렬적이 아니라 앞의 조건에 속한 것이라는 것.
첫번째 예시의 if는 for에 속한 것이고, 두번째 예시의 for는 앞의 for에 속한 것이다.
# list comprehension
[i for i in range(10) if i % 2 == 0]
# output : [0, 2, 4, 6, 8]
[f"{i}x{j}={i * j}" for i in range(2, 10) for j in range(2, 10)]
# output : ['2x2=4',
'2x3=6',
'2x4=8',
'2x5=10',
'2x6=12',
... 중략]
zfill(n), ljust(n, "str"), rjust(n, "str")
이진수를 표현하는데 주로 사용한다. n자리 숫자로 자동으로 만들어 준다.
'1111'.zfill(10)
# output : '0000001111'
map
(https://www.geeksforgeeks.org/python-map-function/)
map(fun, iter)
보통 함수는 람다형식으로 사용한다.
또, map만 호출하면 메모리값을 출력하기 때문에 적절한 자료형으로 출력해야 한다. 아래는 list로 감쌌다.
i = [1, 3, 5]
list(map(lambda x: x + 1, i))
# output : [2, 4, 6]
zip
(https://www.programiz.com/python-programming/methods/built-in/zip)
쉽게 말해 각각을 튜플로 묶어준다. 이 때, 최소 길이를 초과하는 iterator가 있을 경우 무시한다.
아래의 경우 7이 매칭될 것이 없어서 zip의 결과물에서 생략되었다.
a = [1, 3, 5, 7]
b = ["f", "s", "t"]
list(zip(a, b))
# output : [(1, 'f'), (3, 's'), (5, 't')]
json.dump, loads
import json
# json 만들기
json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
# json 읽기
json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
2, 8, 10진법
내장 함수로 bin(), oct(), hex()가 존재
a = int(input())
print(bin(a))
print(oct(a))
print(hex(a))
10
0b1010 (bin)
0o12 (oct)
0xa (hex)
만약 2진수, 8진수, 16진수를 10진수로 변경해야겠다면 int의 두번째 인자에 n진수를 넣어주면 된다.
사실 int() 함수의 2번째 인자는 디폴트값이 10이기 때문에 생략했을 경우 10진수의 문자열이 숫자로 변환되는 것입니다.
print(int('0b101010', 2))
print(int('0o52', 8))
print(int('0x2a', 16))
format() 내장 함수를 이용하면 숫자를 다른 진수로 바꿀수 있고, #을 빼고 적으면 접두어를 제외할 수 있습니다. #을 넣고 적으면 접두어(0o, 0x...)를 넣어줍니다.
format(42, 'b') '101010' # binary는 2진수
format(42, 'o') '52' # oct는 8진수
format(42, 'x') '2a' # hex는 16진수
format(42, 'X') '2A' # hex인데 대문자로 표기함. (값은 같음)
format(42, 'd') '42' # demical로 10진수
format(42, '#b') '101010' # binary는 2진수
format(42, '#o') '52' # oct는 8진수. #를 붙여 0o 생략
format(42, '#x') '2a' # hex는 16진수. #를 붙여 0x 생략
...
이를 이용해 다음과 같이 42를 진수 변환해주었습니다.
"int: {:d}, bin: {:b}, oct: {:o}, hex: {:x}".format(42)
# output : 'int: 42, oct: 52, bin: 101010, hex: 2a'
ASCII
ord => ASCII에서 숫자로
chr => 숫자에서 ASCII로
a = "A"
b = ord(a)
print(ord(a)) # 65
print(chr(b)) # A
비트 연산자 (Bitwise Operator)
python으로 하드웨어를 다루려면 비트 연산자를 알아둬야 합니다.
&, |, ^의 경우에는 일반적인 논리 연산자에서도 쓰니 패스하고, ~, >>, <<에 신경씁시다.
~는 -(값 +1)을 출력하게 된다. 정확히는 2의 보수의 값을 출력한다.
보수에 대해서는 ndb796.tistory.com/4 darrengwon.tistory.com/863 설명을 참고하자.
<< 는 각 비트를 왼쪽으로 옮김(shift). 한번 옮길 때마다 *2^n 하는 효과
>> 는 각 비트르 오른쪽으로 옮김(shift). 한번 옮길 때마다 /2^n 하는 효과
a = int(input())
print(~a) # -(val + 1)
print(a << 1) # *2
print(a >> 1) # /2
positional argument(*args), key argument(**kargs)
def plus(a, b, *args, **kwargs):
print(args)
print(kwargs)
plus(1, 3, 5, 3, 3, 4, hello="hello", who="me")
// args에는 (5, 3, 3, 4)라는 tuple
// kwargs에는 {'hello': 'hello', 'who': 'me'}라는 dict
Class
기본적인 클래스
# 클래스는 대문자로 시작하는게 규칙
class Cal:
# 고정값
name = "darren"
# 인스턴스한테 입력받음
def __init__(self, a, b, say):
self.a = a
self.b = b
self.say = say
def sum(self):
print(f"{self.a} + {self.b} = {self.a+ self.b}")
def say_name(self):
print(f"{self.name} says {self.say}")
# instanciation (인스턴스 만들기)
# new 같은거 없다.
cal = Cal(3, 4, "hello guys")
cal.sum()
cal.say_name()
chaining이 가능하도록 만들어보았다.
class Cal:
name = 'darren' # static
# constructor
def __init__(self, value):
self.value = value
# method
# self는 해당 클래스로 생성되는 인스턴스 자신을 말함. js로 치면 this
def getValue(self):
return self.value
def add(self, num):
self.value = self.getValue() + num
return self
# instanciation (인스턴스 만들기)
cal = Cal(5)
print(cal.getValue())
print(cal.add(100).add(200).getValue())
class 2 (내장 프로퍼티)
dir(Car)를 까보면 다음과 같이 해당 클래스의 프로퍼티들이 나온다.
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'doors', 'seats', 'start', 'wheels', 'windows']
__str__ : 인스턴스 자체를 출력 할 때의 형식을 지정해주는 함수
class Car():
wheels = 4
doors = 4
windows = 4
seats = 4
# method
def __str__(self):
return f"car with {self.wheels} wheels"
# instanciation
porche = Car()
# __str__는 인스턴스 자신을 출력할 때를 다루는 메서드입니다.
print(porche)
// <__main__.Car object at 0x00ACF028> 가 나올 것이라고 생각하지만
// car with 4 wheels가 나온다
__init__ : 초기화 메서드. 해당 인자가 가진 기본적인 프로퍼티들을 설정할 수 있다.
class Car():
def __init__(self, *args, **kwargs):
# self는 해당 클래스로 생성된 인스턴스 자신을 가리킨다
self.wheels = 4
self.doors = 4
self.windows = 4
self.seats = 4
# 인스턴스 생성시 넘겨준 값들을 기본 프로퍼티로 넘겨주자
self.color = kwargs.get("color", "black")
self.price = kwargs.get("price", "don't know")
porche = Car(color="red", price="expensive")
print(porche.price) // expensive
mini = Car()
print(mini.price) // 기본 값인 "don't know"
class 상속
class Car():
def __init__(self, *args, **kwargs):
self.wheels = 4
self.doors = 4
self.windows = 4
self.seats = 4
self.color = kwargs.get("color", "black")
self.price = kwargs.get("price", "don't know")
# method
def __str__(self):
return f"car with {self.wheels} wheels"
class Convertible(Car):
# 확장한 class에서 확장의 대상이 된 class에 덧씌우고 싶다면 super를 호출하자
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.time = kwargs.get("time", 10)
# 확장한 class에서 새로운 메서드를 만들 수 있다.
def take_off(self):
return "take_off!"
porche = Convertible(color="red", price="expensive", time="20")
private 변수
class Person:
def __init__(self, name, age, secret):
self.name = name
self.age = age
# 비공개 속성이므로 외부에서 접근 불가
self.__secret = secret
def threat(self):
# 비공개 속성은 내부 메서드에서만 접근 가능
print(f"secret is {self.__secret}")
darren = Person("darren", 25, "he is hitman")
print(darren.name) # darren 출력
print(darren.secret) # 오류!
darren.threat() # 비공개 속성을 출력 가능함
'Programming Language > 🐍 Python' 카테고리의 다른 글
파일 io (0) | 2020.05.27 |
---|---|
잡다한 메서드, 내장 함수, 외장함수들 (0) | 2020.05.27 |
pip과 pipenv(가상환경)에 대한 이해 (0) | 2020.05.10 |
csv 내장 모듈을 이용한 csv 파일 생성 (0) | 2020.05.10 |
python 환경 변수 세팅, python 경로 찾기 (0) | 2020.04.19 |