2 분 소요

pip install -e .는 setup.py와 연관되어 있다!

pip install -e .를 해보았는데…

knu_studycafe프로젝트에서 pip install -e .를 해보았는데,

image-20240224021956913

위와 같이 에러가 떴다. 아무래도 pip install -e .를 하기 위해서는 둘중에 하나가 필요한 것 같다.

  1. setup.py
  2. pyproject.toml

그래서 이 연관성에 대해서 찾아보았다. 그랬더니 이런 제목을 보게되었다.

파이썬 프로젝트를 패키지화하기(setup.py)([링크](https://data-newbie.tistory.com/770))

일반적으로 우리가 분석을 하다 보면, 다양한 함수나 클래스를 정의하게 된다.

이럴 경우 가장 귀찮은 경우가 이러한 함수들을 매번 관리하는 것이나, 호출해오는데 많은 어려움이 있다.

아래와 같이 코드를 조직화핸다고 해보자.

src/
	plot.py
	process.py
notebooks/
	exploration.ipynb

보통 자신이 만든 함수를 이용하려면 같은 디렉터리에 있어야 가능하지만, src에 있는 패키지를 사용하고 위해서는 아래와 같은 코드가 필요하다.

기본적으로 특정환경에서 site-package에 있는 것을 라이브러리를 불러오는 방식으로 되어있기 때문에 src에 있는 것을 불러오기 위해서는 필요하다.

import sys
sys.path.append('./../src')

그렇지만, 우리가 매번 작업을 하다 보면, 폴더의 디렉터리를 변경할 필요가 있고, 이것을 특정 사람들에게 공유를 한다고 할 때도 디렉터리가 일치하지 않으면, 작동하지 않는다는 단점이 있다.

Python패키지는 pip install {package}를 사용하여 설치할 수 있는 Python 파일의 모음이다.

pip는 코드를 찾을 위치를 알 수 있도록 Python구성을 처리해야 한다.

바로 패키지 생성은 간단하다. setup.py파일만 추가하면 된다.(또는 pyproject.toml도 가능!!)

## setup.py
from glob import glob
from os.path import basename, splitext
from setuptools import find_packages, setup

setup(
	name='my_package',
	version='0.1',
	packages=find_packages(where='src'),
	package_dir={'':'src'},
	py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')],
)

그때, 위와 같은 방식으로 구조를 맞춰주는 것이 좋다.

레이아웃을 약간 변경하여 my_package/ 디렉토리에 코드를 넣고 __init__.py 파일을 추가한다.

src/
	my_package/
		__init__.py
		plot.py
		process.py
notebooks/
	exploration.ipynb
setup.py

setup.py가 있는 폴더에서 아래 코드를 돌리면 된다고 한다.

우리는 계속 수정을 할것이니 develop가 맞을 것이다.

python setup.py develop

직접 개발/수정/디버그를 안한다고 하면 다음과 같다.

python setup.py install
  • install하는 경우(아래그림)
image-20240224023731541
  • develop하는 경우(아래그림)
image-20240224023916568

추가적으로 해당 프로젝트에서 SOLID원칙을 S(SRP)를 고수하고 있다는 것을 알게 되었다.

파이썬 클린코드라는 DOC를 보면(링크), SOLID라는 원칙이 있는데 각 철자마다 의미가 있다.

  • S-SRP(단일책임원칙): 소프트웨어 컴포넌트는 단 하나의 책임을 져야한다.
  • O-OCP(개발/폐쇄원칙): 한 측면에서는 개방되어 있으면서도 다른 측면에서는 폐쇄되어야 한다는 원칙이다.
  • L-LSP(리스코프 치환 원칙): 프로그램을 변경하지 않고 하위 타입의 객체로 치환이 가능해야 한
  • I-ISP(인터페이스 분리 원칙): 다중 메서드를 가진 인터페이스가 있다면 더 적은 수의 메서드를 가진 여러개의 메서드로 분할하는 것이 좋다.
  • D-DIP(의존성 역전 원칙): 코드가 세부사항이나 구체적인 구현에 적응하도록 하지 않고 추상화된 객체에 적응하도록 하는 것

나의 스터디카페프로젝트에서 exit_room.py파일의 코드들을 넣어보니 SRP(단일책임원칙)을 기반으로 안티패턴으로 구현되도록 코드가 짜여져 있다고 한다.(그런가???ㄷㄷ?).

파일에서 데이터를 읽고 선택된 좌석정보를 반환하는 단일 작업을 수행하며, 별도의 함수로 분리해야 할 부분이 없기 때문이라고 Sourcery가 답해주었다. 참고로 여기서 말하는 Sourcery는 vscode에 확장팩으로 붙어있는 ChatGPT이다. 그래서 특정 함수를 구현하고, 그옆에 뜨는 버튼, Explain Code를 누르면 해당 코드에 대한 설명문이 뜨더라(대단하네용). 매우 유요한 것 같고, 그 외에 다른 기능도 있어 나중에 써보려고 한다.


start_page.py를 기본 템플릿으로 해서 그 위에 그림을 그리는 형식인 것 같다.

아래 그림은 purchase.py에 있는 코드이다.

image-20240224074952114

보면은, if 분기문을 쓰고 그게 참이 되면 start_page.py로부터 데이터를 가져와서(from start_page), 그 안에 있는 클래스를 써먹는 형식(import start_page)인 것이다.

registration.py

  1. import 모듈

    • tkinter
    • start_page
    • datetime
  2. class

    • registration(SRP원칙에 따라 하나의 py파일에 하나의 클래스를 넣은 듯 하다)
  3. 함수

    • def __init__(self, parent)
    • def calc_date(self, day)
    • def save_time_info(self, due_date)
    • def canvas_click(self, event)
    • def show_image(self, image_path)
  4. canvas_click(self,event)에 대해서

  5. 총 7가지의 분기문이 내제되어 있다.

    1)[뒤로가기]버튼을 눌렀는지?

    2)[상품구매]버튼을 눌렀는지?

    3)[질문(1)]3일권을 선택했는지?

    4)[질문(2)]7일권을 선택했는지?

    5)[질문(3)]한달권을 선택했는지?

    6)[질문(4)]분기권을 선택했는지?

    7)[질문(5)]반기권을 선택했는지?

파워셀에서 가상환경 실행이 안되면? 파워셀정책을 수정해야한다.

문제>

PS C:\Users\yhon1\Documents\GitHub\knu_studycafe\env\Scripts> .\activate
.\activate :  시스템에서 스크립트를 실행할  없으므로 C:\Users\yhon1\Documents\GitHub\knu_studycafe\env\Scripts\Activate.ps1 파일을 로드할
  없습니다. 자세한 내용은 about_Execution_Policies(https://go.microsoft.com/fwlink/?LinkID=135170) 참조하십시오.
위치 :1 문자:1
+ .\activate
+ ~~~~~~~~~~
    + CategoryInfo          : 보안 오류: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

분석>

파워셀에서 실행정책으로 인해 스크립트를 실행할 수 없는 것으로 보인다. 이것은 보안설정으로 인해 발생하는 문제라고 한다.

해결>

이 문제를 해결하기 위해 파워셀 실행정책을 변경할 수 있다.’

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

하지만 이 명령어는 파워셀 세션단위로 적용되기에 파워셀이 꺼지고 다시 실행하면 위 보안정책이 다시 비활성화됩니다.

즉 파워셀에서 가상환경 킬때마다 위 명령어를 사전에 적어줘야 합니다.

그리고 나서 env/Scripts에 들어가서 activate가 아니라,

./activate

를 적어주어야 한다.

댓글남기기