undefined와 null의 차이를 알아보자


환경

  • Javascript


undefined와 null

undefined

  • 변수가 값을 할당받지 않았을 때 사용되는 원시 값(primitive value)입니다.
  • 함수의 반환이 명시적으로 없으면 undefined를 반환합니다.
  • 원시 자료형 중 하나
// test default
let test;
console.log('variable test is ' + test);

// if statement
if (test === undefined) {
  console.log('variable test is ' + test);
}

// if statement
if (undefined) {
  console.log('undefined is considered as true');
} else {
  console.log('undefined is considered as false');
}

// type test in if statement
// return type of typeof function is string
if (typeof(test) === 'undefined') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNothing() {
  let c;
}
console.log('testReturnNothing returns ' + testReturnNothing());

// check which is not defined
if (typeof(notDefinedVariable) === 'undefined') {
  console.log('variable notDefinedVariable is not defined');
}
variable test is undefined
variable test is undefined
undefined is considered as false
variable test value is undefined and type is undefined
testReturnNothing returns undefined
variable notDefinedVariable is not defined


null

  • 의도적으로 객체나 변수가 비어있음을 나타내는 원시 값입니다.
  • API에서는 대개 객체를 기대했지만, 어떤 적합한 객체도 존재하지 않을 때 반환합니다.
  • 불리언(Boolean) 자료형에서는 거짓을 의미합니다.
// test default
let test = null;
console.log('variable test is ' + test);

// if statement
if (test === null) {
  console.log('variable test is ' + test);
}

// if statement
if (null) {
  console.log('null is considered as true');
} else {
  console.log('null is considered as false');
}

// type test in if statement
// return type of typeof function is string
// its return type is not 'null' it is 'object'
if (typeof(test) === 'object') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNull() {
  return null;
}
console.log('testReturnNull returns ' + testReturnNull());
variable test is null
variable test is null
null is considered as false
variable test value is null and type is object
testReturnNull returns null


비교

undefined

  • 아직 할당되지 않았음을 의미하는 값

null

  • 의도적으로 비어있음을 나타내는 값

기타

  • ==를 사용 시 둘은 같으며 ===를 사용 시 둘은 다릅니다.
  • ===의 경우에 type까지 같이 비교하기 때문에 그렇습니다. 각각의 type은 아래처럼 다릅니다.
typeof(null)         // object
typeof(undefined)    // undefined

null === undefined   // false
null == undefined    // true

!null                // true
!undefined           // true


참고자료

Difference between undefined and null


Environment and Prerequisite

  • Javascript


undefined and null

undefined

  • It is a primitive value used when a variable has not been assigned a value.
  • A function returns undefined if explicitly nothing is returned.
  • One of primitive types
// test default
let test;
console.log('variable test is ' + test);

// if statement
if (test === undefined) {
  console.log('variable test is ' + test);
}

// if statement
if (undefined) {
  console.log('undefined is considered as true');
} else {
  console.log('undefined is considered as false');
}

// type test in if statement
// return type of typeof function is string
if (typeof(test) === 'undefined') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNothing() {
  let c;
}
console.log('testReturnNothing returns ' + testReturnNothing());

// check which is not defined
if (typeof(notDefinedVariable) === 'undefined') {
  console.log('variable notDefinedVariable is not defined');
}
variable test is undefined
variable test is undefined
undefined is considered as false
variable test value is undefined and type is undefined
testReturnNothing returns undefined
variable notDefinedVariable is not defined


null

  • It is a primitive value that represents the intentional absence of any object value.
  • In APIs, null is often retrieved in a place where an object can be expected but no object is relevant.
  • Treated as falsy for boolean operations.
// test default
let test = null;
console.log('variable test is ' + test);

// if statement
if (test === null) {
  console.log('variable test is ' + test);
}

// if statement
if (null) {
  console.log('null is considered as true');
} else {
  console.log('null is considered as false');
}

// type test in if statement
// return type of typeof function is string
// its return type is not 'null' it is 'object'
if (typeof(test) === 'object') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNull() {
  return null;
}
console.log('testReturnNull returns ' + testReturnNull());
variable test is null
variable test is null
null is considered as false
variable test value is null and type is object
testReturnNull returns null


Comparison

undefined

  • Value which represents not defined yet

null

  • Intentional value that it is absence

etc

  • It is equal when use == operator but it will be not equal when use === operator.
  • Because === operator compare not only value but also type. Its type is different like below.
typeof(null)         // object
typeof(undefined)    // undefined

null === undefined   // false
null == undefined    // true

!null                // true
!undefined           // true


Reference

pyenv-virtualenv를 이용해 가상환경에서 만든 파이썬을 crontab에 추가해 실행하는 방법을 알아보자


환경

  • Linux
  • pyenv
  • pyenv-virtualenv


글 배경

배경

  • 파이썬 버전에 따른 의존성을 없애기 위해 pyenvpyenv-virtualenv와 같은 가상환경을 사용하는데 가상환경에서 만든 코드를 crontab에서 실행할 상황이 생겼다.
  • crontab뿐만 아니라 systemd에 서비스를 등록할 때나 쉘스크립트를 작성해서 실행할 때도 적용 가능하다.


사전 지식

파이썬 모듈과 경로

  • 결국 파이썬을 실행할 때 중요한 부분은 여러가지가 있겠지만 모듈이 저장된 위치와 사용할 파이썬이 어디에 위치하냐가 중요하다.


sys.path

  • sys.path: 파이썬 모듈을 사용할 때 참조하는 경로를 저장하고 있는 리스트입니다.
  • import를 사용해서 모듈을 가져올 때 참조하게 됩니다.
>>> import sys
>>> sys.path
['', '/home/twpower/.pyenv/versions/3.6.2/lib/python36.zip', '/home/twpower/.pyenv/versions/3.6.2/lib/python3.6', '/home/twpower/.pyenv/versions/3.6.2/lib/python3.6/lib-dynload', '/home/twpower/.pyenv/versions/jupyter-notebook/lib/python3.6/site-packages']


pyenv versions

  • pyenv를 통해 설치된 여러 파이썬 버전들을 볼 수 있는 명령어
  • pyenv-virtualenv를 통해 만든 가상환경들도 목록에 나온다.
$ pyenv versions
* system (set by /home/twpower/.pyenv/version)
  3.5.2
  3.5.3
  3.6.1
  3.6.2
  3.6.2/envs/jupyter-notebook
  3.6.2/envs/test
  jupyter-notebook
  test


pyenv path

  • 위에 나온 pyenv versions에 해당하는 파이썬 및 모듈들은 $(pyenv root)/versions의 경로에 있다.
$ ls /home/twpower/.pyenv/versions/
3.5.2  3.5.3  3.6.1  3.6.2  jupyter-notebook  test


적용 방법

방법1 - 사용할 가상환경의 파이썬을 직접 선택

  • pyenv-virtualenv는 가상환경마다 사용하는 파이썬이 다릅니다. 그렇기에 사용하는 경로도 다르고 그에 따른 sys.path도 다릅니다.
  • pyenv-virtualenv에서 사용하는 파이썬을 직접 이용해 .py파일을 실행하면 됩니다.
  • 경로: [pyenv root]/versions/[virtualenv name]/bin/[python version]

crontab

30 20 * * * /home/twpower/.pyenv/versions/jupyter-notebook/bin/python3.6 /home/twpower/test.py


방법2 - 스크립트에서 “pyenv activate”를 사용

  • 쉘 스크립트로 파일을 만들고 해당 스크립트에 pyenv activate를 통해 가상환경을 만들어주고 파이썬 코드를 실행합니다.

test.sh

#!/bin/bash

source /home/twpower/.bash_profile
source /home/twpower/.bashrc

pyenv activate jupyter-notebook
python /home/twpower/test.py

crontab

30 20 * * * /home/twpower/test.sh


참고자료

Add python file which runs in pyenv-virtualenv to crontab and run it.


Environment and Prerequisite

  • Linux
  • pyenv
  • pyenv-virtualenv


Post Background

Background

  • To isolate dependency in python versions, people use pyenv and pyenv-virtualenv. By using those softwares we can make virtual environment which can run python code file. I encounter run python code file in crontab which runs in virtual environment.
  • It can be used in not only crontab but also systemd’s service and shell script.


Prior knowledge

Python Module and Path

  • When running python code file, there are many important things to care. However this post focus on python module path and which python you use.


sys.path

  • sys.path: A list of strings that specifies the search path for modules.
  • Refer sys.path when load python module using import.
>>> import sys
>>> sys.path
['', '/home/twpower/.pyenv/versions/3.6.2/lib/python36.zip', '/home/twpower/.pyenv/versions/3.6.2/lib/python3.6', '/home/twpower/.pyenv/versions/3.6.2/lib/python3.6/lib-dynload', '/home/twpower/.pyenv/versions/jupyter-notebook/lib/python3.6/site-packages']


pyenv versions

  • Show number of python versions which installed by pyenv
  • Also includes pyenv-virtualenv’s virtual environment.
$ pyenv versions
* system (set by /home/twpower/.pyenv/version)
  3.5.2
  3.5.3
  3.6.1
  3.6.2
  3.6.2/envs/jupyter-notebook
  3.6.2/envs/test
  jupyter-notebook
  test


pyenv path

  • pyenv versions python and modules are located in $(pyenv root)/versions path.
$ ls /home/twpower/.pyenv/versions/
3.5.2  3.5.3  3.6.1  3.6.2  jupyter-notebook  test


How To Apply

Method1 - Use virtual environment’s python directly

  • Each pyenv-virtualenv has its own python. So its python path is different and also sys.path is different.
  • Use python code file directly which is in pyenv-virtualenv.
  • Path: [pyenv root]/versions/[virtualenv name]/bin/[python version]

crontab

30 20 * * * /home/twpower/.pyenv/versions/jupyter-notebook/bin/python3.6 /home/twpower/test.py


Method2 - Use “pyenv activate” in script

  • Add pyenv activate to make virtual environment in shell script and run python code.

test.sh

#!/bin/bash

source /home/twpower/.bash_profile
source /home/twpower/.bashrc

pyenv activate jupyter-notebook
python /home/twpower/test.py

crontab

30 20 * * * /home/twpower/test.sh


Reference

구조 분해 할당을 통해서 값을 받아보자.


환경

  • Javascript


구조 분해 할당

정의

  • 구조 분해 할당(Destructuring assignment): 배열이나 객체에서 원소나 속성을 해체하여 그 값들을 각각의 변수에 담을 수 있도록 하는 구문
  • 다양한 예제들은 아래 ‘참고자료’에 있는 링크에 많이 있다.


간단한 예제

배열 구조 분해

let arr = [1, 2, 3, 4, 5];
let [a, b, ...c] = arr;

console.log(arr);
console.log(a);
console.log(b);
console.log(c);
[ 1, 2, 3, 4, 5 ]
1
2
[ 3, 4, 5 ]

객체 구조 분해

let object = {
  a: 1,
  b: "test",
  c: [1, 2],
  d: { name: "test", age: 28 },
};

// Key must be same
let { a, b, c, d } = object;

/* Assign to different variable name example
let { a: e, b: f, c: g, d: h } = object;
*/

console.log(a);
console.log(b);
console.log(c);
console.log(d);
1
test
[ 1, 2 ]
{ name: 'test', age: 28 }


사용

  • 이러한 구조 분해 할당(Destructuring assignment)을 사용하면 함수에서 반환된 값을 여러개로 받을 수 있다. 이는 정확하게는 객체나 배열을 반환하고 이를 구조 분해 할당을 통해 받는거다.

배열 반환 예제

function test() {
  return [1, 2, 3, 4, 5];
}

let [a, b, ...c] = test();

console.log(a);
console.log(b);
console.log(c);
1
2
[ 3, 4, 5 ]

객체 반환 예제

function test() {
  let object = {
    a: 1,
    b: "test",
    c: [1, 2],
    d: { name: "test", age: 28 },
  };

  return object;
}

let { a, b, c, d } = test();

console.log(a);
console.log(b);
console.log(c);
console.log(d);
1
test
[ 1, 2 ]
{ name: 'test', age: 28 }


참고자료