본문으로 바로가기

JS 사용자를 위한 python 정리

category Programming Language/🐍 Python 2020. 4. 20. 04:06
 

3.8.2 Documentation

Python 3.8.2 문서 환영합니다! 파이썬 3.8.2 설명서의 한국어 번역입니다. 설명서의 파트들: 파이썬 3.8 의 새로운 기능은? 2.0 이후의 모든 "새로운 기능" 문서 자습서 여기에서 시작하세요 라이브러리 레퍼런스 베개 밑에 넣어 두세요 언어 레퍼런스 문법과 언어 요소들을 설명합니다 파이썬 설정 및 사용법 여러 플랫폼에서 파이썬을 사용하는 법 파이썬 HOWTO 특정 주제에 대한 심층적인 문서 파이썬 모듈 설치하기 파이썬 패키지 색인 및 기타

docs.python.org

 

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

 

 

Built-in Functions — Python 3.8.2 documentation

Built-in Functions The Python interpreter has a number of functions and types built into it that are always available. They are listed here in alphabetical order. abs(x) Return the absolute value of a number. The argument may be an integer or a floating po

docs.python.org

# 문자열이나 배열의 길이
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 ....) 자주 헷갈린다.

 

Python Module Index — Python 3.8.2 documentation

numbers Numeric abstract base classes (Complex, Real, Integral, etc.).

docs.python.org

 

-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() # 비공개 속성을 출력 가능함

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체