'Language'에 해당하는 글 98건

<들어가기 전에>

기본적으로, windows pip를 사용하기 위해서는 virtualenv가 아닌이상

administrator permission으로 cmd를 실행해야 한다


<Twisted install>

필자의 경우 pip로 설치 시 cl.exe와 io.h 에러가 발생하는데, cl.exe는 PATH 문제라 치고, io.h는 못찾겠다


http://hashcode.co.kr/questions/4649/%EC%9C%88%EB%8F%84%EC%9A%B0-twisted-%EC%84%A4%EC%B9%98-%EC%A4%91-c-%EB%B9%8C%EB%8D%94-%EC%98%A4%EB%A5%98


https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted


위 링크에서 twisted 인스톨러를 다운받을 수 있다고 한다

twisted index를 찾아가서

자신의 cpython 버전과 비트수에 맞춰서 whl 파일을 설치하자 (OS의 비트수가 아니라 파이썬의 비트수임을 유의하자)


whl 파일 경로에서 아래 커맨드를 실행하자

pip install <twisted-whl>


문제없이 설치가 완료된다


아래는 시행착오 과정


https://stackoverflow.com/a/43098806


C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat


cl.h solution


필자의 경우, Visual Studio 2017이 설치되어있고 아래의 경로를 env PATH에 추가해주었다


C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\bin\Hostx64\x64


그랬더니 io.h가 발생하더라




io.h solution


env INCLUDE에 아래 경로를 추가해주었다


C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include



'Language > python' 카테고리의 다른 글

[python] scrapy concurrent_requests  (0) 2018.03.27
[python] win32api ImportError  (0) 2018.03.26
[python] scrapy with form-data  (0) 2018.03.23
python scrapy 한글 인코딩  (0) 2018.03.16
[python] multiprocessing  (0) 2018.01.15

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

scrapy: Web Crawling Framework


beautifulsoup과 비교해보자면, beautifulsoup은 parseing library인 반면

scrapy는 더 강한 abstraction을 제공하는 framework이다


scrapy.Request(url=URL, callback=self.parse, method=METHOD, body=BODY, meta=META)


기본적인 사용방법은 위와 같은데 body에 form-data를 전송할 경우

FormRequest를 사용해야한다.


scrapy.FormRequest(..., formdata=FORM_DATA, ...)


request의 body(data)는 form-data, json, wav 등 여러가지 타입이 될 수 있다

request는 이 타입을 header 중 Content-Type field에 명시해야한다


scrapy에서는 FormRequest 클래스를 통해 이러한 수고를 덜어준다


Request 클래스는 Content-Type 헤더가 명시되어 있지 않으므로, server에서 body data를 form-data 타입으로 인식하지 못한다



'Language > python' 카테고리의 다른 글

[python] win32api ImportError  (0) 2018.03.26
[python] windows pip Twisted install error  (0) 2018.03.23
python scrapy 한글 인코딩  (0) 2018.03.16
[python] multiprocessing  (0) 2018.01.15
[Language] [IDE] PyCharm Run Path (Working Directory)  (0) 2018.01.05

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

python scrapy를 통해 사이트를 크롤링 하여 json으로 저장하는데 인코딩 문제가 발생했다


원인은 python json 라이브러리의 ensure_ascii=True 옵션


project의 settings.py 파일에 아래 라인을 추가하여 해결하였다


FEED_EXPORT_ENCODING = 'utf-8'


---


인코딩 결과를 확인하려면 vim과 terminal(ssh client)의 인코딩도 싱크해야한다


cat >> ~/.vimrc

set enc=utf-8


terminal의 인코딩도 utf-8로 설정



'Language > python' 카테고리의 다른 글

[python] windows pip Twisted install error  (0) 2018.03.23
[python] scrapy with form-data  (0) 2018.03.23
[python] multiprocessing  (0) 2018.01.15
[Language] [IDE] PyCharm Run Path (Working Directory)  (0) 2018.01.05
[python] tornado package  (0) 2018.01.01

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

new Thread() {

@Override

public void run() {

// code

}

}


같은 기능의 코드


class MyThread  extends Thread {

@Override

public void run() {

// code

}

}


// ...

new MyThread();




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

https://social.msdn.microsoft.com/Forums/vstudio/en-US/685e5679-cf65-4495-b85c-74eb6fbf1b40/the-scc-display-information-package-did-not-load-correctly-visual-2015-update-3-1402543101?forum=visualstudiogeneral

'Language' 카테고리의 다른 글

[C] open() vs fopen() (low-level vs high-level I/O API)  (0) 2018.04.05
[Java] anonymous subclass (Thread)  (0) 2018.03.15
[Javascript] vue-cli example  (0) 2018.01.06
[Node.js] npm install option  (0) 2018.01.06
[Javascript] ESLint? / 설치  (0) 2018.01.05

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def func(q, start, interval):
    result = 0
    for i in range(start, start+interval):
        result += i
    q.put(result)
 
proc_cnt = 4
q_list = []
proc_list = []
output = 0
start = 0
interval = int(1000000000 / proc_cnt)
 
# process create & start
for i in range(proc_cnt):
    q = Queue()
    p = Process(target=func, args=(q, start, interval))
    p.start()
    start += interval
    q_list.append(q)
    proc_list.append(p)
 
# receive output from processes
for q in q_list:
    temp = q.get()
    # print(temp)
    output += temp
print(output)
 
# vs single-processing
result = 0
for i in range(1000000000):
    result += i
print(result)
 
cs



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

vue-CLI: vue Command Line Interface

vue project를 init/build/run 하는데에 사용한다 (특히 webpack template으로)


npm install -g vue-cli # 오래걸림

vue init webpack vueapp01 # webpack template으로 vue project init # 오래걸림2

(unit test와 e2e tests는 사용하지 말자. 다운로드 시간 줄이게)

cd vueapp01

npm install # dependencies install

npm run dev # package.json-script-dev 실행

npm run build # package.json-script-build 실행 -> dist directory에 production build


src/main.js에서 import문을 사용하는데, 이것은 ES6 syntax이며 브라우저에서도 사용할수 있다고한다

그에 대한 내용은 아래 사이트 참고

https://medium.com/dev-channel/es6-modules-in-chrome-canary-m60-ba588dfb8ab7


ES6의 import문은 CommonJS의 require()와 비교된다

그에 대한 내용은 아래 사이트

https://blueshw.github.io/2017/05/16/ES-require-vs-import/


참고:

https://medium.com/codingthesmartway-com-blog/vue-js-2-quickstart-tutorial-2017-246195cfbdd2


---


<vue single file component>

src/App.vue를 보면 <template>, <script>, <style> 3개의 block으로 이루어져있는 걸 확인할 수 있다

이것은 vue의 single file component이다

javscript 프로젝트 규모가 클 경우, 모듈(컴포넌트)를 분리해서 관리 해야하므로 single file component을 사용한다

<vue-loader>

이 컴포넌트는 vue-loader를 통해 CommonJS module로 변환된다 (webpack에서 사용하기 위해)

<webpack>

이 CommonJS module은 webpack(build tool)에 의해서 사용된다


webpack을 통해서 모듈들을 사용하여 프로젝트를 빌드할수 있다

simple project부터 시작하고 싶을 경우

webpack 템플릿 대신, webpack, vue-loader만을 사용하는 webpack-simple tempalte으로 vue init하자


<conclusion>

vue+webpack이 처음이라면 vue init webpack-simple을 사용하자

vue 파일은 single file component이며, vue-loader를 통해서 webpack build에 사용될수 있다

<template>, <script>, <style> 3개의 block으로 이루어져있다


---


vue-cli를 이용하면

 - vue --- vue-loader --- webpack을 통해 코드를 모듈별로 관리할 수 있다 (코드관리 효율적)

 - hot reload를 통해 빠른 개발이 가능하다

 - Flask(Jinja2), Django(Django Template)에서 vue를 사용할 때 template syntax conflict 문제를 피할 수 있다

(production build해보면 암)



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

npm install pkg <option>


-g

global에 install (not only working directory)

ex) ESLint


--save

working directory의 package.json 파일의 dependencies에 추가 (실행하기 위하여 필요한 dependencies)

ex) React


--save-dev

working directory의 package.json 파일의 devDependencies에 추가 (개발할 때만 필요한 dependencies)

ex) ESLint


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

 

ECMAScript + Linter(Syntax Check)


일단 ESLint 설치부터 해보자

ESLint는 Node.js로 작성된 프로그램이다

npm install -g eslint


npm init

eslint --init


 

test.js 파일 작성

eslint test.js # error occured

eslint test.js --fix # auto-fix


추가)

eslint --ext .js,.vue src --fix

src 디렉토리에서 extension이 js or vue인 파일들을 fix


참고

https://subicura.com/2016/07/11/coding-convention.html


'Language' 카테고리의 다른 글

[Javascript] vue-cli example  (0) 2018.01.06
[Node.js] npm install option  (0) 2018.01.06
[Language] Javascript 변수, 함수, Closure  (0) 2018.01.05
[Language] Node.js? Webpack? Javascript? CommonJS?  (0) 2018.01.05
[Language] Webpack이란?  (0) 2018.01.04

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

// 문자열 변수

var str = 'hello';


// 오브젝트 변수

var obj = { first: 'world' };


// function 변수

var func = () => { ... };


// function

function func() { ... }


// closure

(() => { alert('closure1'); })();



var closure2 = (() => (

{

three: () => (3),

alert: (n) => {

alert(n)

}

}

))();


closure2.three() // 3

closure2.alert(5)


<Closure 사용 이유?>

함수를 사용한 후 메모리에 남아있지 않게 한다


'Language' 카테고리의 다른 글

[Node.js] npm install option  (0) 2018.01.06
[Javascript] ESLint? / 설치  (0) 2018.01.05
[Language] Node.js? Webpack? Javascript? CommonJS?  (0) 2018.01.05
[Language] Webpack이란?  (0) 2018.01.04
[Language] Node.js와 CommonJS  (0) 2018.01.04

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<Node와 CommonJS>

Node.js에서 아래와 같은 문법을 본적이 있을것이다


var react = require('React');


필자는 그냥 Node.js만의 문법이라고 생각했었다

하지만 이것은 CommonJS의 문법이다. CommonJS라는 모듈화 Specification을 Node.js가 채택했기 때문에

Node.js에서 require(...) 문법을 사용할 수 있는 것이다

(RequireJS가 아니다)


모듈을 만들 때는


exports.aaa = bbb

또는

module.exports = aaa


이러한 specification(명세)을 따르게 되는데, CommonJS를 알고있어야 사용할 수 있을 것이다

Node는 Javascript일 뿐이라고 생각했는데, 그 사이에 CommonJS가 있었다

물론 ES2015==ES6==ECMAScript6 Standard도 있고.


<Webpack과 CommonJS>

Webpack은 CommonJS와 AMD:Async Module Definition 포맷을 모두 지원한다

Webpack은 Module화 시스템이다

Webpack을 사용하면 Javascript를 여러개의 모듈로 분리하여 작성하고, 모듈 사이의 dependency에 따라 build할수 있다

Javascript로 프로젝트를 한다면 Webpack은 거의 필수라는 생각이 든다

여기까지는 Webpack 소개였고


Webpack을 공부하는데, CommonJS을 모르니까 Webpack이 뭔지 이해가 안되더라.

Webpack이 AMD를 지원하긴 하지만, Node도 CommonJS를 쓰니까 Webpack도 CommonJS로 대체로 쓰나보다

Webpack을 공부하기 전에 CommonJS부터 먼저 공부하자!


<Javascript와 CommonJS>

Javascript의 Module Specification인 CommonJS

Server-side인 Node에서 CommonJS는 사용하기 편리하지만

Clisnt-side에서는 <script> 태그로 include하다보면 변수 이름이 겹치는 문제가 발생할 수 있다

그래서 Client-side에서는 AMD가 더 편리하다...고 하지만!

Webpack과 함께라면 여전히 우리는 CommonJS와 함께 할수 있다


<vue와 webpack>

vue를 client-side에서 개발하는데 너무 비효율적인 느낌이 들었다

이때 webpack와 commonJS를 알게되었고, webpack은 잘 모르겠고 commonJS는 client-side에서 사용하는데에 약간 문제가 있었다(=일반적이지 않다)


그래서 계속 webpack을 공부해서 이해해보니, Javascript 개발환경도 매우 편리해졌구나 라는 생각이 들었다


<conclusion>

Node가 대세처럼 뜨면서 Javascript로 개발하는 범위가 넓어졌다

Node 속에는 CommonJS가 있고, Webpack도 CommonJS를 기반으로 사용하고(필자 주변의 대체로)

Javascript를 공부해보겠다면 Node와 함께 Webpack, CommonJS도 공부하면 도움이 될것이다


지금까지 공부내용 정리겸 포스팅하였다


'Language' 카테고리의 다른 글

[Javascript] ESLint? / 설치  (0) 2018.01.05
[Language] Javascript 변수, 함수, Closure  (0) 2018.01.05
[Language] Webpack이란?  (0) 2018.01.04
[Language] Node.js와 CommonJS  (0) 2018.01.04
[C언어] library(.so file) compile/build  (0) 2018.01.01

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<pycharm에 대하여>
pycharm.. python IDE 중에서는 가장 큰 것 같고, auto-completion도 나쁘지 않다

키워드 replacement도 있다

replace하는 변수이름이 test처럼 일반적이면 상관없는 키워드들도 다 바꿔버려서 에러를 만드는거나

코드정리를 자기멋대로 해버리고 설정이 불편하고...

어쨌든! 장단점이 있지만 필자는 현재 pycharm을 사용중이다


<run - working directory>

pycharm에서 아래 코드를 실행하였다


with open('file') as f: ...


그런데 그럴리가 없는데 에러가 났다!

아래 코드를 실행해보았더니


import os

print(os.getcwd())

# output: C:\Windows\System32


위와 같이 출력되었다

하고싶은 얘기는 간단하다

pycharm에서 run 했을 때 path, location이 왜 project directory가 아니냐!를 찾아보다가

working directory configuration을 해야한다는 것을 알았다

이 글에서 하고싶은 이야기는 간단하다. run configuration에서 working directory를 설정할 수 있다


실행 화살표 버튼 옆에 왼쪽에 있는 버튼 (ex: 프로젝트 이름일수도 있고, 아닐수도 있고...)을 누르면

Edit Configuration이 나오는데, 거기서 working directory를 project directory로 설정해주면 된다


수정 후 run 했을 때 위 코드는 에러가 발생하지 않고 잘 동작하였다


pycharm은 개인적으로 기본 설정이 필자와 잘 안맞고, 설정도 복잡하게 되어있는것 같다

그렇다고 못쓸정도는 아니지만!

필자처럼 path나 location으로 서치해서 헤매는 사람들이 있을까봐 메모겸, 공유겸 포스팅하였다


'Language > python' 카테고리의 다른 글

python scrapy 한글 인코딩  (0) 2018.03.16
[python] multiprocessing  (0) 2018.01.15
[python] tornado package  (0) 2018.01.01
[python] ctypes: ARRAY vs POINTER 차이/비교  (0) 2018.01.01
[python] == vs is 차이/비교  (0) 2018.01.01

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Javascript 모듈화 specification(명세)로 CommonJS와 AMD:Async Module Definition가 있다

그리고 Webpack은 이 둘을 모두 지원하는 Javascript의 모듈화 시스템이다


필자의 주변에서는 CommonJS가 더 많이 쓰이는 것 같다. Node에서도 CommonJS를 사용하고.

아래 Naver D2 참고 사이트에서도 CommonJS로 Webpack 예제를 보여준다 (더 간결하다는 이유로)


<참고>

JavaScript 모듈화 도구, webpack: http://d2.naver.com/helloworld/0239818


JavaScript 표준을 위한 움직임: CommonJS와 AMD: http://d2.naver.com/helloworld/12864

요약: Server-side는 CommonJS 간결, Client-side는 AMD가 더 유연



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Node에서 사용하는 

var my_module = require('my_module')

이 신텍스가 바로 CommonJS이다

즉 Node는 CommonJS를 사용한다 (RequireJS가 아니라)


require()을 호출하면 무엇이 리턴될까?

리턴값은 my_module.js 파일의 module.exports이다


my_module.js 파일에서

module.exports = ...

위와 같이 선언하고, require를 통해서 리턴받을 수 있다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

tornado: asynchronous networking library, web framework


web framework는 flask, django가 많이 쓰이고

async는 asyncio라는 standard package가 최근 버전에 추가되었다


그렇다고 tornado가 사용되지 않는 것은 아니지만, 기왕이면 필자는 tornado보다는 flask/asyncio를 사용하려 한다




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

sizeof(c_int*4) # (c_int*4) size

sizeof(POINTER(c_int)) # POINTER size


CFUNCTYPE을 사용할 때는 POINTER를 사용해야 호환된다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

== -> compare vaule

is -> compare object (memory address)


ex) 

a = 'str'

b = input() # str

a is b # False

a == b # True



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

(1)은 연산식을 작성할 때 사용하는 소괄호로 인식하고

(1,)은 tuple을 생성하는 것이고 인식한다


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

read()/write()의 parameter/return type이 바뀐다


'r'/'w' -> str type

'rb'/'wb' -> bytes type


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

gcc lib.c -o lib.so -fPIC -shared


-fPIC: Position Independent Code

'Language' 카테고리의 다른 글

[Language] Webpack이란?  (0) 2018.01.04
[Language] Node.js와 CommonJS  (0) 2018.01.04
[C/C++] gcc option (추천 옵션)  (0) 2017.12.18
[C] 2D 배열 포인터 example (Pointer to 2D array)  (0) 2017.12.18
[OOP] private 키워드의 필요성  (0) 2017.12.15

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

python에서 인스턴스 멤버변수를 선언할 때 def __init__(self) 안에서만 할수있다고 알고있었다

그런데 굳이 __init__을 사용하지 않아도 멤버변수를 선언할 수 있었다


1
2
3
4
5
6
class Test1(object):
    def __init__(self):
        self.num = 5
 
class Test2(object):
    num = 5
cs


https://stackoverflow.com/a/26529574

위 링크에 아주 친절하게 설명되어있다


결론은 아래와 같이 간단하게 사용해도 웬만하면 문제없다는 뜻이다

귀찮게 __init__, self를 사용하지 않아도 된다


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<virtualenv?>

virtual environment를 만들어주는 패키지다

gradle, maven처럼 프로젝트의 라이브러리 버전을 매니지먼트해준다


<라이브러리 버전 관리?>

virtualenv는 프로젝트에서 라이브러리를 많이 사용할 때, 라이브러리 버전을 관리하기위해 필요해진다

라이브러리 버전 관리는 왜 필요할까?

1. 다른 환경(PC)에서 프로젝트를 개발/실행할 때, library version compatibility issue가 발생하지 않도록 해준다

2. 이 프로젝트에서 사용하는 라이브러리들을 정리하기 간편하다


2번은 virtualenv를 실행하고, 필요한 라이브러리들을 다운받고, 

pip freeze > req.txt

위 커맨드를 통해 req.txt file로 redirection하면 dependency library들의 리스트를 만들수 있다. 그리고

pip install -r req.txt

다른 환경에서 위 커맨드를 통해 필요 라이브러리들을 손쉽게 인스톨할수있다


<사용법>

위에서 virtualenv 사용이유에 대해서 살펴보았다. 이제 사용법을 알아보자

virtualenv venv

위 커맨드를 실행하면 현재 경로에 venv 디렉토리가 생성된다

venv/Scripts/activate

위 커맨드로 venv를 시작할 수 있다

pip freeze

위 커맨드로 venv가 잘 실행되었는지 확인할 수 있다 (인스톨한 라이브러리가 없다고 보여야함)

deactivate

venv를 빠져나올 수 있다


---


<주의>

venv 디렉토리를 생성하고 다른 곳으로 옮겨서 사용하면 제대로 동작하지 않는다

그땐 바뀐 경로에서 다시

virtualenv venv

커맨드를 실행하여 그 경로에 다시 venv를 적용하여야한다


그리고 windows powershell에서는 사용하기 귀찮으므로 cmd를 추천한다

또한 cmd에서는 경로에 / 대신 \(back slash)를 사용하여야한다
(이래서 mac를 쓰나보다)

example: venv\Scripts\activate



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

python class에는 슈퍼클래스에 접근하기 위해 사용하는 super() 메서드가 있다


python3에서는 문제없이 잘 동작하는데, python2는 그렇지 않다


class MyClass: pass


위와 같이 선언하면 super()를 호출할 때 python2에서는 에러가 발생한다 (super()의 파라미터가 type이 아닌 classobj일 때)


그래서 아래와 같이 object를 상속받아 선언해야한다


class MyClass(object): pass


---


python2에서는 super() 등 별도의 목적을 위해,

python3에서는 python2 compatibility를 위해 사용한다 (__future__처럼)


좀더 내부적으로 보면, python2에서 상속없이 선언한 클래스는 old-style class로 선언되기 때문에

new-style class로 선언하기 위해 object 클래스를 상속받는 것이다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

WSGI는 Web Server Gateway Interface의 약자인데, web server와 web application의 interface 기능을 하는 python framework라고 위키에 설명되어있다

Django, flask는 WSGI를 사용하고있다. 그리고 인증 등을 위해 WSGI의 middleware를 사용하고있다


django보다는 flask가 더 공부하는 재미가 있어서, django에서 사용하던 middleware를 flask로 migrate할 계획이다

진행되면 추가포스팅하도록 하겠다


---


django middleware (create your own middleware)

https://docs.djangoproject.com/ko/2.0/topics/http/middleware/


django deprecation middlewaremixin

https://github.com/django/django/blob/master/django/utils/deprecation.py


flask WSGI 미들웨어에서 후킹하기

http://flask-docs-kr.readthedocs.io/ko/latest/quickstart.html#wsgi

app.wsgi_app = MyMiddleware(app.wsgi_app) # wsgi_app == method



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

[python] Django란?

Language/python 2017. 12. 29. 23:21

<Web Application Framework for python>

Django는 이전 글에서 언급했듯, python으로 작성된 web application framework이다

(이전 글 (Web 개발의 특징 / Django F/W를 사용해보며 느낀 점): http://ssaemo.tistory.com/124)


<Django의 Abstraction>

다른 프레임워크들도 그렇듯, 웹앱 개발을 엄청나게 추상화되어있어 웹앱 아키텍처의 사전지식이 없어도 쉽게 개발할수 있는 것이 장점이다

하지만 양날의 검인 것이, 웹앱 아키텍처에 대해서 잘 알고있어도 프레임워크 사용에 큰 도움은 되지않는다


<MTV Pattern>

Django는 MTV pattern을 사용한다

MTV는 Model, Template, View인데, 


Model은 db table 생성 및 데이터 처리(CRUD)에 사용된다

Model class가 db table이고 instance가 데이터(db row)이다

table 생성은 migrate를 통해서 이뤄지고, CRUD는 queryset이었나?


Template은 presentation logic을 담당하여 HTML 뼈대(skeleton)를 만드는데에 사용된다

rendering(=data binding)은 view에 의해 이뤄진다

(여담으로 Flask는 jinja2 Template engine을 사용하는데 Django는 자체 템플릿 엔진이 있다)


View는 request를 receive하고 적절히 처리하여 response를 send한다

적절한 처리라는 것은, 특정 template에 model로부터 읽어온 data를 binding(rendering)하는 것이다

VIew의 역할은 request를 처리하는 것이다. template, model과 상호작용하여 HTML은 generate하고 response하는 것,


<routing>

Django는 routing 기능도 포함하고 있다

urls.py에 path를 설정하여 적절한 view에 routing한다


<register>

사용해보진 않았는데, Model class를 admin에 register하면

admin page에서 그 Model을 확인하고 관리할 수 있다


<ORM: Object Relational Mapper>

Django의 QuerySet을 의미하는 듯 하다.

Post라는 Model이 있다고 하자. Post.objects.all() 또는 filter() 등의 메서드들을 호출하면 QuerySet이 리턴된다

그럼 QuerySet은 왜 쓰는걸까? 현재까지의 생각으로는, SQL을 몰라도 DB에 Access할수있다는 것이 QuerySet의 기능이다

SQL을 몰라도 DB에 데이터를 저장하고, 읽을 수 있다

그에 따라, DB 변경이 쉬울 것으로 생각된다 (그럴 일이 있을까?)

SQL도 사용할 수 있다. Model.objects.raw(sql)을 사용해서.

QuerySet을 모를때는 이게 어떻게 동작하는지 파악하기가 어려웠다 (프레임워크의 너무 큰 의존성)

가장 큰 문제는, django database engine에 있는 database만 사용할 수 있다는 것이다

Elasticsearch를 DB처럼 사용하고싶어도, django QuerySet을 통해서는 사용할 수 없다

자유도가 낮다고 말할수도 있겠다

어쨌든 Django의 ORM은 QuerySet(Model에 있는)이고, 장점보다는 단점이 더 크게 느껴졌다 개인적으로.


(또 여담. Flask에서 사용하는 SQLAlchemy ORM도 정의된 engine들 한정이다.

db로 elasticsearch를 사용하고싶어서 찾아봤던건데, elasticsearch-py 자체에 ORM 기능이 있어서 필요없을듯

근데 django는 db 세팅이 강제라서 맘에 안듬. 여윽시 flask가 최고시다)


<tutorial>

# install django

pip install django # 현재 최신버전은 2.0


# create a django project

# django를 설치하면 django-admin 커맨드가 생긴다

django-admin startproject mysite .


# 프로젝트 안에 app을 하나 더 생성하려면 이렇게?

django-admin startapp myapp .


프로젝트를 생성하면 manage.py가 생기는데, 이 파일로 project에 command를 실행할 수 있다

migrate, runserver, test 등.


---


<django INSTALLED_APPS>

# 일부 INSTALLED_APPS는 DB를 사용한다. 그러므로 manage.py migrate를 실행해야한다.

# migrate는 DB table 생성 커맨드이다. # makemigrations는 Model 선언 후, migrate 전 실행

https://docs.djangoproject.com/ko/2.0/intro/tutorial02/

# DocType

https://github.com/sabricot/django-elasticsearch-dsl

# sqlite3 in volatile memory

https://stackoverflow.com/questions/39098008/django-rest-framework-without-database


<django Celery task>

== async task queue(background process)

# CELERY_BEAT_SCHEDULE, crontab

 - crontab(minute=0, hour='*/3') # 3시간마다

 - crontab(minute='*/15') # 15분마다

 - crontab(minute=0, hour=0) # 매일 0시0분



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<What is the Django?>

Django는 Flask와 함께 대표적인 python으로 작성된 Web Application Framework이다

둘의 차이점은 Flask가 더 가볍다는 것인데, 이건 여기서 다루려는 내용은 아니고.

웹 애플리케이션 프로젝트를 맡게되어서 Django를 언급하게 됐다


<Why use the Django?>

개발툴을 고를 때 Node.js(Network Application Development S/W Platform)를 사용하려고 했었는데

이전 버전인 Django를 재개발하는 것이었기 때문에, 기한의 압박을 덜기위해 Django를 사용하게 됐다


Django를 며칠 다뤄보니 알게된 것이 있다

예전에 이미 Flask, Django, Spring, Node.js(얘는 플랫폼) 등 여러 프레임워크들의 기본 기능(라우팅, 뷰 등의 구성)들은 살펴보았지만, 이제 생각해보니 제대로 개발해본 경험이 없었다.

웹보다는 네이티브에 더 흥미가 있었기 때문이다

왜 그랬을까?


<Web 개발의 특징>

이제서야 깨달았는데, 나는 코드레벨 성능/구조 최적화에 가장 흥미가 있다

그러나 Web 개발은 그런 점에서 반대에 있다고 생각한다 (그래서 흥미가 안생겼었는데, 자세한 이유는 잘 못 느꼈다)

Web은 특성상, 성능 최적화보다는 다양한 클라이언트에 대한 Compatibility(호환성)에 더 포커싱되어있다

사용상의 속도이슈 이전에, 사용 가능성 자체의 문제이기 때문이다

그래서 jQuery 라이브러리가 나왔다.

HTML/CSS/JS의 IE, Chrome, Firefox 등 다양한 브라우저를 더 편리하게 지원하기 위해서. (그 외에도 충분히 편리한 기능은 많다)

Client-side의 Static page에는 jQuery가 나온 반면,


Server-side의 Dynamic Page, 즉 Web Application은 PHP, JSP, ASP와 같은 Script Language부터 시작되었다 (그전에 있었던 native binary와 CGI는 스킵하자)

이 언어들은 View와 Data Logic이 분리되어있지 않아서 유지보수에 어려움이 있었다

그래서 MVC 패턴과 함께 Spring과 같은 웹 애플리케이션 프레임워크가 등장하게 되었다

(위 내용들은 오피셜이 아니고 모두 필자의 개인적인 생각들이므로 오해 없기를)

웹 앱 프레임워크는 MVC 패턴을 이용하여 Data Logic과 View를 분리함으로써 유지보수 문제를 해결해주었다


이후 다양한 웹 애플리케이션 프레임워크들의 발전과 함께 Angular, React, Vue와 같은 프론트엔드 프레임워크들도 등장했다

웹 앱 프레임워크 -> 추상화를 통해 웹앱을 점점더 쉽개 개발할수 있도록 발전하였고

프론트엔드 프레임워크 -> 이젠 멀티브라우저보다는 수많은 모바일 디바이스들의 호환성에 포커싱하였다


필자가 생각하는 웹 개발의 역사는 이러한데, 핵심은 이것이다

백엔드/프론트엔드 프레임워크들은 추상화를 통해 웹개발을 더 쉽게 만들고 / 성능보다는 클라이언트 호환성에 포커싱되어있다는 것이다

Django는 심지어 SQL을 몰라도 ORM을 통해 Table을 만들고 데이터 SELECT/INSERT/DELETE까지 할수있는 걸 보고 꽤많이 놀랐다

더 나아가서, 이것은 웹앱 아키텍처를 몰라도 웹앱을 개발할수있게 해주었고, 부정적으로 말하면 프레임워크의 의존성이 너무 커졌다

결국 하고싶은 말은 이것이었다. 프레임워크를 공부해봐야, 다른 프레임워크에 적응하는데에는 거의 도움이 안된다 (2020.05 수정)

서비스 개발관점에서는 최고지만 공부 관점에서는 장점이 하나도 없었다. 그래서 흥미가 없었다

(그리고 심각한 추상화로 인해 프레임워크 구조로부터 실제 동작을 이해/파악하기가 어렵다는 점이 매우 끔찍함. (2020.05 수정)

웹앱 아키텍처를 알아도 프레임워크를 새로 공부해야함)


그리고 계속 말해왔듯이 클라이언트 호환성, 이 외에도 잡다하게 신경쓸 부분들이 너무 많았다 (데이터 로직보다는 뷰의 중요성이 더 큰 느낌)

이것도 필자의 흥미를 저해하는 이유 중 하나였다


<이와중에 Node.js>

Node.js는 Framework가 아니라 Platform이라고 wiki에 설명되어있다. 플랫폼이라고 하는것보다는 프로그래밍 언어라고 하는것이 더 와닿을 것이다.

언어도 하나의 플랫폼이기 때문.

처음에는 Async I/O라는 점 때문에 흥미가 생겼지만 중요한 것은 그것이 아니었다

PLATFORM. 이것은 심각하게 추상화되어있지 않다. 웹앱 아키텍처를 이해하고있다면 Node.js에 굉장히 빠르게 적응할수 있다 (2020.05 수정)

그래서 프레임워크는 서비스 개발자에게, Node.js는 프로그래머에게 더 잘맞는다고 생각한다

Node.js는 공부하는 의미가 있다! 그래서 매우 흥미롭다.

게다가 웹 한정이 아니라 네트워크 애플리케이션 개발을 위한 플랫폼이므로, 사용범위가 더 넓다

그래서 다음에는 꼭 Node.js 프로젝트를 해보려고 한다


<Conclusion>

Django를 사용해보면서, 웹앱 프레임워크의 굉장한 추상화와 불편함을 느끼게 되었다

그래서 왜 그동안 웹개발에 흥미가 없었는지, Node.js에는 왜 흥미가 생겼는지 생각하게 되었고

이 외에 Django, ORM의 목적/기능에 대해서도 생각해보게 되었다 (이것은 기회가되면 나중에 작성하기로)

그래서 그런 주저리 생각들을 서술해보았다

(원래는 Django 사용법에 대해서 정리해놓으려했는데 삼천포로 샜다. 이건 다음 포스팅에.

그리고 글쓸 시간여유좀 있었으면 좋겠다)


---


 (2020.05 수정)


대략 2년 반전에 쓴 글을 다시 읽어보니, 좁은 시각으로 Django는 너무 부정적으로 Node.js는 너무 긍정적으로 써놓았었습니다 ㅋㅋ

글 읽으시는 분들은 이 점 감안해서 읽어주시고 오해 없으시면 합니다.


Django도 좋은 프레임워크이며, 개발 생산성을 높이는 데에 큰 도움을 줍니다. 추상화가 많이 되어있지만 공부를 해보면 어떻게 동작하는지도 알 수 있습니다.


Node.js에도 (아직 사용해보지는 않았지만) Django와 같이 ORM 등을 제공해주는 웹 프레임워크가 있습니다. Node.js를 사용하신다면 ORM같은 부분보다는 싱글 스레드 기반 비동기 아키텍처를 잘 이해하는 것이 중요할 것입니다


글 읽어주셔서 감사합니다

'Language > python' 카테고리의 다른 글

[python] WSGI, Middleware (flask, django)  (0) 2017.12.29
[python] Django란?  (0) 2017.12.29
[python] 추상클래스(abstract class) - abc module  (0) 2017.12.16
[python] logging example  (0) 2017.12.16
[python] unittest library - simple example  (0) 2017.12.15

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

자주 사용하는, 유용한, 추천 gcc 옵션


gcc


-Wall

# warning all


-std=c11

# c11 standard (ex: for(int i=0))


-g

# debug


-fPIC -shared

# so 파일 컴파일 시



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<code example>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
void func(char(*)[256]);
 
int main()
{
    char* arr[4= { "a""b""c""d" };
    char** pArr = arr; // &arr == int(*)[25] // arr == int*
 
    char arr2[4][256= { "A""B""C""D" };
    char(*pArr2)[256= arr2;
 
    printf("%c %c \n", arr[0][0], pArr[0][0]);
    printf("%c %c \n", arr2[0][0], pArr2[0][0]);
    func(pArr2);
}
 
void func(char(*)[256]) {}
cs


2D 배열 포인터 선언 및 

파라미터에서 2D 배열포인터 사용법의 예제코드이다


<2D 배열 포인터에 대해서 포스팅하는 이유>

배열은 포인터로, 포인터배열은 더블포인터와 같다

그런데 간혹 포인터배열과 2차원 배열이 혼동될 때가 있다

그래서 그 차이를 명확히 하여 메모하기 위해 이 글을 작성한다


2D 배열 포인터를 굳이 써야할 상황이 있나? 있다

지역변수로 2차원 배열을 선언하는 것은 쉽다

그러나 malloc으로 메모리를 할당받았을 때 일반적으로는 포인터에 할당받고 [i*width+j] 형식으로 [i][j]를 대신하여 사용한다 (1차원 배열은 문제없다)

이것은 귀찮고 실수가 발생할 여지가 비교적 많다


이때 2D 배열 포인터로 할당받음으로써 [i][j] 형식으로 인덱싱 할수있는 것이다

코드는 간단해지며 실수가 줄어들 것이다


이렇게 2가지 이유에서 2D 배열 포인터에 대하여 글을 작성하게 되었다


'Language' 카테고리의 다른 글

[C언어] library(.so file) compile/build  (0) 2018.01.01
[C/C++] gcc option (추천 옵션)  (0) 2017.12.18
[OOP] private 키워드의 필요성  (0) 2017.12.15
[OOP] [Design Pattern] State Pattern  (0) 2017.12.11
cmake 변수 설정방법  (0) 2017.12.07

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<code example>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from abc import *
 
class PQBase(ABC):
    @abstractmethod
    def add(self, item):
        pass
    
    @abstractmethod
    def remove_min(self):
        pass
 
class PQ(PQBase): # implements by unordered list
    def __init__(self):
        self._pq = []
        
    def add(self, item):
        self._pq.append(item)
    
    def remove_min(self):
        pq = self._pq
        
        min = pq[0]
        for i in pq:
            if min > i:
                min = i
 
        pq.remove(min)
        return min
    
    def is_empty(self):
        return len(self._pq) == 0
 
if __name__ == '__main__':
    pq = PQ()
    pq.add(5)
    pq.add(3)
    pq.add(1)
    pq.add(2)
    pq.add(4)
 
    while not pq.is_empty():
        print(pq.remove_min())
cs


1. ABC 클래스를 상속(derive)받는다

2. 필수구현 메서드에 @abstractmethod 데코레이터?를 사용한다


<etc>

작은 규모에서는, 굳이 abc module을 사용하지않고 메서드 각각에

raise Exception('Not Implemented')

를 사용하여 구현하여도 큰 차이 없을듯 하다


multiple inherit class의 경우에는 conflict를 방지하기 위해 ABC 대신 metaclass=ABCMeta를 사용한다는 듯 하다

위 예제 기준에서는 ABC 상속만으로도 충분하다

'Language > python' 카테고리의 다른 글

[python] Django란?  (0) 2017.12.29
Web 개발의 특징 / Django F/W를 사용해보며 느낀 점  (5) 2017.12.29
[python] logging example  (0) 2017.12.16
[python] unittest library - simple example  (0) 2017.12.15
[python] numpy 함수들  (0) 2017.12.14

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<code example>

1
2
3
4
5
6
7
import logging
 
logging.basicConfig()
log = logging.getLogger('hj')
log.setLevel(logging.DEBUG)
 
log.debug('msg')
cs


<logging level>

LevelNumeric value
CRITICAL50
ERROR40
WARNING30
INFO20
DEBUG10
NOTSET0

<API 설명>

logging.basicConfig()

# stderr StreamHandler와 Formatter를 설정함으로써, console에서 log를 확인할 수 있게 해준다


logging.getLogger(logger_name)

# get logger instance


log.debug(msg)

# log debug message


<필요성/편리성>

print()를 통해서 logging을 할 경우와 비교

logging module을 사용하면,

 - log를 켜고 끌수 있다

 - 한줄로 여러 개의 stream에 log를 쓸수있다


<참조>

https://docs.python.org/3/library/logging.html


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

사용중인 블로그 스킨이 방명록을 지원하지 않습니다.

초대장을 받고싶으신 분들은 댓글 또는 블로그 설명의 메일로.