파이썬이란?

파이썬이란 1990년 암스테르담의 귀도 반 로섬(Guido Van Rossum)에 의해 만들어진 인터프리터 언어이다. 귀도는 이 파이썬이라는 이름을 본인이 좋아하는 "Monty Python's Flying Circus"라는 코미디 쇼에서 따왔다고 한다. 파이썬(Python)의 사전적인 뜻은 고대 신화 속의 파르나수스(Parnassus) 산의 동굴에 살던 큰 뱀으로서, 아폴로가 델파이에서 파이썬을 퇴치했다는 이야기가 전해지고 있다. 대부분의 파이썬 책 표지와 아이콘이 뱀 모양으로 그려져 있는 이유가 여기에 있다.

현재 파이썬은 국내에서는 많이 알려져 있지 않지만 외국에서는 학습의 목적뿐만 아니라 실용적인 부분에서도 많이 사용되고 있는데 그 대표적인 예는 바로 구글(Google) 이다. 구글에서 만들어진 소프트웨어의 50%이상이 파이썬으로 만들어졌다고 한다. 이 외에도 유명한 것을 몇가지 들어보면 Dropbox(파일 동기화 서비스), Django(파이썬 웹 프레임워크)등을 들 수 있다.

또한 파이썬 프로그램은 공동작업과 유지보수가 매우 쉽고 편하기 때문에 이미 다른 언어로 작성된 많은 프로그램과 모듈들이 파이썬으로 다시 재구성되고 있는 상황이다. 국내에서도 그 가치를 인정받아 사용자층이 더욱 넓어져 가고 있고, 파이썬을 이용한 프로그램을 개발하는 기업체들이 늘어가고 있는 추세이다.

파이썬 특징

인간다운 언어

프로그래밍이란 컴퓨터에 인간이 생각하는 것을 입력시키는 행위라고 할 수 있다. 앞으로 살펴볼 파이썬 문법들에서도 볼 수 있겠지만 파이썬은 사람이 생각하는 방식을 그대로 표현할 수 있도록 해 주는 언어이다. 따라서 프로그래머는 굳이 컴퓨터식 사고 방식으로 프로그래밍을 하려고 애쓸 필요가 없다. 이제 곧 어떤 프로그램을 구상하자마자 생각한 대로 쉽게 술술 써내려가는 여러분의 모습에 놀라게 될 것이다. 아래 예문을 보면 이 말이 쉽게 이해될 것이다.

if 4 in [1,2,3,4]: print ("4가 있습니다")

위의 예제는 다음처럼 읽을 수 있다.

"만약 4가 1,2,3,4중에 있으면 "4가 있습니다"를 출력한다."

프로그램을 모르더라도 직관적으로 무엇을 뜻하는지 알 수 있지 않겠는가? 마치 영어문장을 읽는 듯한 착각에 빠져든다.

쉬운 문법으로 인한 빠른 학습

어려운 문법과 수많은 규칙들에 둘러싸인 언어에서 탈피하고 싶지 않은가? 파이썬은 문법 자체가 아주 쉽고 간결하며, 사람의 사고 방식과 매우 닮아있다. 배우기 쉬운 언어, 활용하기 쉬운 언어가 가장 좋은 언어가 아닐까? 참고로 프로그래밍 경험이 있는 어떤 사람(Eric Raymond)은 파이썬을 공부한지 단 하루만에 자신이 원하는 프로그램을 작성할 수 있었다고 한다. 

강력함

파이썬으로 프로그래머는 대부분의 모든 일들을 해낼 수가 있다. 물론 시스템 프로그래밍, 하드웨어 제어, 매우 복잡하고 많은 반복연산 등은 파이썬과는 어울리지 않는다. 하지만 이러한 몇 가지를 제외하면 파이썬으로 할 수 없는 것은 거의 없다고 해도 과언이 아니다.

또한 파이썬은 위의 약점을 극복할 수 있게끔 다른 언어로 만든 모듈을 파이썬 프로그램에 포함할 수가 있다. 파이썬과 C는 찰떡궁합이란 말이 있다. 즉, 프로그램의 전반적인 뼈대는 파이썬으로 만들고 빠른 속도를 필요로 하는 부분은 C로 만들어서 파이썬 프로그램 안에 포함시키자는 것이다. (정말 놀라울 정도로 영악한 언어가 아닌가?) 사실 파이썬 라이브러리 중에는 순수 파이썬만으로 제작된 것도 많지만 C로 만들어진 것도 많다. C로 만들어진 것들은 대부분 속도가 빠르다.

무료

파이썬은 오픈소스이므로 당연히 무료이다. 언제 어디서든 파이썬을 다운로드하여 사용할 수 있고, 사용료를 지불해야 할 필요가 없다.

간결함

파이썬은 간결하다. 이 간결함은 파이썬을 만든 귀도(Guido)의 의도적인 산물이다. 만약 어떤 언어(Perl?)가 하나의 일을 하기 위한 방법이 100가지라면 파이썬은 가장 좋은 방법 1가지를 선호한다. 이 파이썬의 간결함이란 철학은 소스코드에도 그대로 적용되어 파이썬 프로그래밍을 하는 사람들은 잘 정리되어 있는 소스코드를 볼 수 있게 되었다. 다른 사람들의 소스 코드가 한눈에 들어오기 때문에 이 간결함은 공동 작업에 매우 큰 역할을 하게 되었다. 다음은 파이썬 프로그램의 예제이다.

# simple.py
languages = ['python', 'perl', 'c', 'java']

for lang in languages:
    if lang in ['python', 'perl']:
        print("%6s need interpreter" % lang)
    elif lang in ['c', 'java']:
        print("%6s need compiler" % lang)
    else:
        print("should not reach here")


위의 프로그램 소스 코드를 이해하려 하지는 말자. 이것을 이해할 수 있다면 당신은 이미 파이썬에 중독된 사람일 것이다.그냥 한번 구경해 보도록 하자. 다른 언어들에서 늘 보이는 단락을 구분하는 괄호({, })문자들이 보이지 않는 것을 확인 할 수 있다. 또한, 줄을 참 잘 맞춘 코드라는 것도 확인 할 수 있다. 줄을 맞추지 않으면 실행이 되지 않는다. 파이썬 프로그래머는 코드를 이쁘게 작성하려고 저렇게 줄맞추어 코딩을 하는것이 아니다. 다만 실행이 되게 하기 위해서 줄을 맞추어야 하는 것이다. 이렇듯 줄을 맞추어 코드를 작성하는 행위는 가독성에 큰 도움을 준다.

 

파이썬으로 할수 있는 것

좋은 프로그래밍 언어와 나쁜 프로그래밍 언어는 이미 정해진 걸까? 그렇다면 어떤것이 최고의 언어일까? 가만히 살펴보면 어떤 언어든지 강한 부분과 약한 부분이 존재한다. 어떤 프로그램을 만들 것인지에 따라 선택해야 할 언어도 달라진다. 한 언어만을 고집하고 그 언어로만 모든 것을 하겠다는 생각은 현실과는 맞지 않는다. 따라서 자신이 만들고자 하는 프로그램을 가장 잘 만들 수 있게 도와주는 언어가 어떤 것인지 알아내고 선택하는 것은 중요한 일이다. 하지만 할 수 있는 일과 할 수 없는 일을 가리기는 쉽지 않다. 왜냐하면 어떤 언어든지 할 수 없는 일은 별로 없기 때문이다. 하지만 한 프로그래밍 언어가 어떤 일에 적합한지에 대해서 아는 것은 매우 중요하다. 따라서 파이썬으로 하기에 적당한 일과 적당하지 않은 일에 대해서 알아보는 것은 매우 가치있는 일이 될 것이다.

파이썬으로 할 수 있는 일은 너무나 많다. 대부분의 컴퓨터 언어가 하는 일을 파이썬은 쉽고 깔끔하게 처리한다. 이것들에 대해서 나열하자면 끝도 없겠지만 대표적인 몇 가지의 예를 들어보도록 하자.

시스템 유틸리티

파이썬은 운영체제(윈도우즈, 리눅스등)의 시스템 명령어들을 이용할 수 있는 도구들을 갖추고 있기 때문에 이러한 것들을 바탕으로 갖가지 시스템 관련한 유틸리티를 만드는 데 유리하다. 여러분은 시스템에서 사용중인 다른 유틸리티성 프로그램들을 하나로 뭉쳐서 큰 힘을 발휘하게 하는 프로그램들을 무수히 만들어 낼 수 있다.

GUI(Graphic User Interface) 프로그램

GUI 프로그래밍이라는 것은 쉽게 말해서 윈도우즈 창같은 프로그램을 만드는 것이다. 파이썬으로 GUI프로그램을 작성하는 것은 다른 언어로 하는 것보다 훨씬 쉽다. 대표적인 것으로 파이썬 프로그램을 설치할 때 함께 설치되는 Tkinter를 들 수 있다. 실제로 Tkinter를 이용한 파이썬 GUI프로그램의 프로그램 소스는 매우 간단하다. 놀라운 사실은 Tkinter를 이용하면 소스코드 단 5줄 만으로도 윈도우즈 창을 띄울 수 있다는 것이다. 이 외에도 wxPython, PyQT, PyGTK등의 Tkinter보다 빠른 속도와 미려한 윈도우 화면을 자랑하는 것들도 있다.

C/C++과의 결합

파이썬은 접착(glue)언어라고도 불리운다. 그 이유는 다른 언어와 함께 잘 어울릴 수 있기 때문이다. C로 만든 프로그램을 파이썬에서 쓸 수 있으며, 파이썬으로 만든 프로그램을 C에서 역시 사용할 수 있다.

웹 프로그래밍

우리는 익스플로러나 크롬, 파이어폭스와 같은 브라우저를 이용하여 인터넷을 사용한다. 누구나 한번쯤 웹 서핑을 하면서 게시판이나 방명록에 글을 남겨 본 적이 있을 것이다. 그러한 게시판이나 방명록을 바로 웹 프로그램이라고 한다. 파이썬은 웹 프로그램을 작성하기에 매우 적합한 도구이며 실제로 파이썬으로 제작된 웹 사이트는 셀 수 없을 정도로 많다.

수치연산 프로그래밍

사실 파이썬은 수치연산 프로그래밍에 적합한 언어는 아니다. 왜냐하면 복잡하고 연산이 많다면 C와 같은 언어로 하는 것이 더 빠르기 때문이다. 하지만 파이썬에서는 Numeric Python이라는 수치 연산 모듈을 제공한다. 이 Numeric Python은 C로 작성되었기 때문에 매우 빠르게 수학연산을 수행한다. 이 모듈을 이용하면 파이썬에서 수치연산을 빠르게 할 수 있다.

데이터베이스 프로그래밍

파이썬은 Sybase, Infomix, Oracle, MySQL, Postgresql등의 데이터 베이스에 접근할 수 있게 해주는 도구들을 제공한다. 또한 이런 굵직한 데이터베이스를 직접 이용하는 것 외에도 파이썬에는 재미있는 함수가 하나 있다. 바로 pickle이라는 모듈이다. 이 모듈은 파이썬에서 쓰이는 자료들을 변형없이 그대로 파일에 저장하고 불러오는 일들을 해 준다.

파이썬으로 할 수 없는 일 

파이썬으로 도스나 리눅스 같은 운영체제, 엄청난 횟수의 반복과 연산을 필요로 하는 프로그램 또는 데이터 압축 알고리즘 개발 프로그램등을 만들기는 어렵다. 즉, 대단히 빠른 속도를 요구하거나 하드웨어를 직접 건드려야 하는 프로그램에는 어울리지 않는다.


장고에서 제공하는 모델을 사용하여 개발할 때, settings.py에 아래와 같이 설정이 되어 있을 것입니다.

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_L10N = True

USE_TZ = True

pgsql 테이블 내 컬럼 타입이 timestamp without time zone인 것을 테이블 스키마를 장고로 inspectdb를 할 시, DateTimeField로 정의가 됩니다.

그리고 사용자는 해당 컬럼에 대해 datetime.now()와 같이 값을 넣을 때, 문제가 발생합니다.

settings.py 에 정의 된 것처럼, timezone이 서울로 되어 입력이 되어야 하지만, 실제 들어간 데이터를 확인해 보면 UTC기준으로 입력이 됩니다. (또한 RuntimeWarning: DateTimeField received a naive datetime 와 같이 warning을 띄울 수 있습니다.)


이러한 문제를 해결하기 위해, import datetime이 아닌 from django.conf import timezone을 사용하여 timezone.now()를 사용합니다. 또한 settings.py 의 USE_TZ = True부분을 USE_TZ = False로 변경합니다.

이는 https://docs.djangoproject.com/en/1.9/ref/settings/#std:setting-USE_TZ 에 나와 있듯이 USE_TZ = True일경우, 장고 내부적으로 시간대를 인식하는 날짜 및 시간을 사용하고 USE_TZ = False일 경우, local time을 사용하게 됩니다. (확인이 필요한 부분이지만 True일 경우, UTC를 기준으로 사용하고 False일 경우, TIME_ZONE에 설정되어 있는 값을 참고하여 local time이 변형됩니다.)

  1. 매드캐스퍼 2018.08.01 12:23

    django.conf 가 아니고 django.utils 인 것 같습니다.

장고 orm이나 파이썬 코드를 보면 *args, **kwargs를 확인할 수 있습니다.

해당 뜻은 어떤 파라미터를 몇개를 받을지 모르는 경우 사용한다 라고 하지만 막연하기 때문에 예를 들어 설명하겠습니다.

*args 

 *args는 파라미터를 몇개를 받을지 모르는 경우 사용하고 튜플 형태로 전달됩니다.

 def test(*args):
    print(args)

test('a','b','c')


#결과 ('a', 'b', 'c')

위처럼 argument로 여러 값을 던지고 해당 함수에서 tuple을 사용할 수 있습니다.


dict타입과 같이 변수 자체를 그대로 넘기면 튜플 내에 데이터 1개로 취급됩니다.

def test(*args):
    print(args)

a = {'name': 'a', 'name2': 'b', 'name3': 'c'}
test(a)


#결과 ({'name3': 'c', 'name': 'a', 'name2': 'b'},)



아래와 같이 dict 변수에 포인터를 붙여서 사용하면 dict 변수내의 키값만 빠져 튜플형태를 이루게 됩니다.

def test(*kwargs):
    print(kwargs)

a = {'name': 'a', 'name2': 'b', 'name3': 'c'}

test(*a)
 
#결과 ('name', 'name2', 'name3')


**kwargs

- 파라미터 명을 같이 보낼 수 있고 kwargs는 딕셔너리 형태로 전달됩니다.

def test(**kwargs):
    print(kwargs)


test(name1='a', name2='b', name3='c')


#결과 {'name2': 'b', 'name3': 'c', 'name1': 'a'}


만약 이미 dict 형태인 값을 가지고 있고, 해당 함수에 변수 자체를 넘기고 싶을 경우 아래와 같이 합니다.


def test(**kwargs):
    print(kwargs)


a = {'name': 'a', 'name2': 'b', 'name3': 'c'}

test(**a)


# 결과 {'name': 'a', 'name2': 'b', 'name3': 'c'}


base.py 

"""
Django settings for polalis project.

Generated by 'django-admin startproject' using Django 1.8.6.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'p5^ykf!%2(8q3lxqfi_+&ivv*xy7!77bcjc9-9^uw#eopu6e7o'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


PROJECT_APPS = (
    'account',
    'bankbook',
    'cashbook',
    'cashreceipt',
    'credit',
    'ebill',
    'etaxbill',
    'finment',
    'library',
    'login',
    'polalis',
    'process',
    'scrapping',
    'situation',
    'slipfix',
    'statement',
    'trade',
    'trialbalance',

)

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_jenkins',
    'rest_framework',
    'rest_framework_swagger',
    'django_crontab',
    'account',
    'bankbook',
    'cashbook',
    'cashreceipt',
    'credit',
    'ebill',
    'etaxbill',
    'finment',
    'library',
    'login',
    'polalis',
    'process',
    'scrapping',
    'situation',
    'slipfix',
    'statement',
    'trade',
    'trialbalance',
)

JENKINS_TASKS = (
    'django_jenkins.tasks.run_pylint',
)

PYLINT_LOAD_PLUGIN = (
    'pylint_django',
)
'''
REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}
'''

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'polalis.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, '../templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

CRONJOBS = [
    ('*/10 * * * *', 'scrapping.cron.scrapping_cron', '>> /tmp/scrapping_cron.log')
]

WSGI_APPLICATION = 'polalis.wsgi.application'



SWAGGER_SETTINGS = {
    'exclude_namespaces': [],
    'api_version': '0.1',
    'api_path': '/',
    'enabled_methods': [
        'get',
        'post',
        'put',
        'patch',
        'delete'
    ],
    'is_authenticated': False,
    'is_superuser': False,
    'unauthenticated_user': 'django.contrib.auth.models.AnonymousUser',
    'permission_denied_handler': None,
    'info': {
        'title': 'Polaris API',
    },
    'doc_expansion': 'none',
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_L10N = True

USE_TZ = True



# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, '../static'),
    './static/',
)


dev.py

from polalis.settings.base import *

CRONTAB_DJANGO_SETTINGS_MODULE = 'polalis.settings.dev'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'polaris',
        'USER': 'sunrise',
        'PASSWORD': '1234',
        'HOST': 'postgres',
        'PORT': '5432'
    },
    'trialbalance': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'polaris_0108',
        'USER': 'sunrise',
        'PASSWORD': '1234',
        'HOST': 'postgres',
        'PORT': '5432'
    },
    'cashbook': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'cashbook',
        'USER': 'sunrise',
        'PASSWORD': '123',
        'HOST': 'postgres',
        'PORT': '5432'
    },
    'papyrus': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'polaris_papyrus',
        'USER': 'sunrise',
        'PASSWORD': '1234',
        'HOST': 'postgres',
        'PORT': '5432'
    },
    'polaris_0108': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'polaris_0108',
        'USER': 'sunrise',
        'PASSWORD': '1234',
        'HOST': 'postgres',
        'PORT': '5432'
    }
}


base.py는 공통적으로 사용하는 부분을 작성하는 파일입니다.

local.py, dev.py 등 세팅환경을 분리하여 작성할 때 사용되며 from polalis.settings.base import * 와 같이 base.py를 참조합니다.

파일경로

SUNRISE(프로젝트) / SUNRISE (앱) / settings(폴더) / base.py, server.py, __init__.py (빨간색 부분은 생성해야함)

세팅

  1. 기존에 사용하던 settings.py 안의 코드를 local.py에 전부 복사/붙여넣기합니다.
  2. TEMPLATES =[  { ... 'DIRS': [os.path.join(BASE_DIR'../../templates')] ... } ] 이와 같이 구성되어 있다면 DIRS를 다음과 같이 변경합니다.
    1. -> 'DIRS': [os.path.join(BASE_DIR'../templates')]
  3. STATICFILES_DIRS = ( os.path.join(BASE_DIR"../static"), ... 이와 같이 구성되어 있다면 os.path.join의 경로를 다음과 같이 변경합니다.

    1. -> os.path.join(BASE_DIR"../static")

  4. local.py는 로컬에서 실행하기 위해 설정한 파일이고, dev.py는 서버에서 실행시키기 위해 만든 파일입니다. 현재 server에서 변경할 부분은 databases의 속성밖에 없으므로, databases의 속성만 변경합니다. (위 코드 참조)
  5. /SUNRISE 앱 내의 wsgi.py 폴더를 살펴보면 os.environ.setdefault("DJANGO_SETTINGS_MODULE""SUNRISE.settings") 이렇게 실행 시, default로 참조할 settings 파일 경로 부분을 다음과 같이 변경합니다.
    1. -> os.environ.setdefault("DJANGO_SETTINGS_MODULE""SUNRISE.settings.local") - 서버일 경우 local 대신 dev를 입력합니다.

실행법

  • 파이참에서 실행할 경우

    1. 상단 메뉴 탭의 Run - Run - Edit Configrations... - Environment - Environment variables: 우측의 ... 버튼 클릭 - DJANGO_SETTINGS_MODULE의 Value값을 SUNRISE.settings.local로 변경


  • 터미널에서 실행할 경우

    • 터미널 창에서 python manage.py runserver (호출할 URL) -- settings파일이 존재하는 폴더=project.폴더.실행시킬 파일
      • e.g,) python manage.py runserver ip주소:80 -- settings=SUNRISE.settings.server


이전 장고의 settings.py 파일을 분리했던 것과 같은 이유로 환경변수를 분리하는 방법을 설명하겠습니다.


코드

import sys


def get(func):
    try:
        for i in range(1, len(sys.argv)):
            settings_str = "--settings="
            settings_index = sys.argv[i].find(settings_str)
            # 받은 argument 중 좌변이 환경변수 분리 키 값일 경우, 우변의 값을 경로를 저장합니다.
            if settings_index != -1:
                # 입력받은 값을 변수에 저장
                actions = sys.argv[i][settings_index + len(settings_str):]

        # 받은 값으로 import로 선언
        tmp = __import__(actions)
        # 선택할 settings 파일명만 선택
        env_name = actions[actions.rfind(".") + 1:]
        # 위에서 구한 함수이름으로 호출
        instance = getattr(tmp, env_name)

    except Exception as e:
        # 아무 입력안될 시, 에러를 내고 프로그램 종료
        print(e)
        print("입력한 파라미터를 확인해주세요")
        exit()

    try:
        # 파라미터로 받은 값을 사용해 동적으로 함수 및 변수들을 호출
        return getattr(instance, func)

    except Exception as e:
        raise e


databases = {
    'default': {
        'DBNAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '5432'
    },
	'other': {
		'DBNAME': 'postgres2',
        'USER': 'postgres',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '5432'
    }
} 


from env import get

# default로 정의되어 있는 데이터베이스 정보를 호출하고 싶은 경우,
get('databases')['default']

파일경로

untitled(패키지) / settings(폴더) / base.py, local.py, ...  (빨간색 부분은 생성해야함)


세팅

직접 파일생성하여 실행할 경우

  1. env.py를 생성하여 위에 작성된 코드를 넣습니다.
  2. main이나 데이터베이스를 호출하는 파일에서 from env import get를 넣어줍니다.
  3. get() 함수를 사용

pip로 다운로드받아서 사용할 경우

virtualenv를 사용하는데 터미널에서 그냥 해당 명령어를 실행시켜 다운로드 받을 경우, 파이썬의 인터프리터는 virtualenv를 바라보고 있는데 설치는 virtualenv가 아닌 파이썬 자체에 모듈이 설치되기 때문에 인식을 할 수 없습니다.

virtualenv를 사용할 경우

  1. 터미널 실행
  2. 사용하고 있는 virtualenv 폴더로 이동
  3. source bin/activate 명령어 실행
  4. pip3 install --trusted-host ip주소 --index-url http://ip주소/simple/ env 명령어 실행

  5. from env import get를 추가하여 get()함수를 사용

virtualenv를 사용하지 않는 경우

  1. 터미널 실행
  2. pip3 install --trusted-host ip주소 --index-url http://ip주소/simple/ env 명령어 실행
  3. from env import get를 추가하여 get()함수를 사용

실행법

파이참에서 실행할 경우

상단 메뉴 탭의 Run - Run... - Edit Configrations... Script parameters에 환경변수가 들어있는 폴더 및 파일명을 작성합니다.

예) 

현재버전은 Script Parameters 부분에 --settings=settings.base 로 입력해야 합니다.


터미널에서 실행할 경우

python 실행파이썬파일 폴더.파일 과 같은 형식으로 호출합니다.

예) python main.py --settings=settings.base

사용법

settings

  • local.py

main.py

databases = {
    'default': {
        'DBNAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '5432'
    },
	'other': {
		'DBNAME': 'postgres2',
        'USER': 'postgres',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '5432'
    }
} 


from env import get
 
print(env('databases')['default'])


와 같이 폴더 구조와 local.py, main.py의 코드가 잡혀있다고 가정합니다.

위 세팅법을 통해 먼저 설치를 한 후, main.py에 from env import get를 추가합니다.

다음 터미널에서 python main.py --settings=settings.local을 입력하여 main.py를 실행시킵니다.

실행결과는 local.py 파일의 databases라는 dict 변수를 읽고 그 중, default에 정의되어 있는 DB 정보를 출력하게 됩니다.

privated pypi 서버

privated pypi서버에 올라온 패키지들의 목록이 궁금하면 등록ip주소/simple url을 입력하면 올라와있는 서버의 패키지를 확인할 수 있습니다.



아래와 같은 dict 타입의 변수가 존재한다고 할 때, 첫 번째와 두 번쨰의 차이점은 무엇일까?

dict_test={"a":"1","b":"2"}
#1
dict_test.clear()
#2
dict_test={}


두 코드 기능은 "지운다" 라는 점에 있어 동일합니다. 하지만 dict_test라는 변수를 재사용할 때, 큰 차이점이 있습니다.


#1의 경우입니다.

dict_test={"a":"1","b":"2"}
 
temp_dict=dict_test
 
dict_test.clear()
print(temp_dict)
 
결과: {}


#2의 경우입니다.

dict_test={"a":"1","b":"2"}
 
temp_dict=dict_test
 
dict_test={}
print(temp_dict)
 
결과: {"a":"1","b":"2"}


#2의 경우, dict_test={}를 할 때, 새로운 {} (비어있는 dict 타입)을 새로 생성하고 dict_test의 값을 {}에 할당합니다. 이 때, temp_dict는 값이 할당되어 있는 예전 변수의 값인 {"a":"1","b":"2"}를 가리키고 있기 때문에, dict_test를 추가하거나 삭제해도 그대로 값이 존재합니다.

반면 #1의 경우, dict_test.clear()를 할 경우, dict_test와 temp_dict 둘 다 가리키고 있는 point의 값을 지워버리기 때문에 temp_dict에 값을 할당하고 clear()를 해도 가리키고 있는 point의 값이 존재하지 않게 됩니다.


+ Random Posts