python

Python 모듈 불러오기

by VICENTE97P4


Dec. 20, 2021, 2:57 p.m.


파이썬에서는 사용자 지정 불러오기를 사용하여 불러오기 방법을 확장할 수 있습니다.

이는 파이썬으로 구현한 리스프인 Hy가 표준 .py, .pyc 이외의 파일을 불러오는 방법을 파이썬에게 알려주는 기술이빈다.

(Hy에 대해서는 추후에 살펴보도록 하겠습니다.)


파이썬은 불러오기 방법을 두 가지 제시합니다.

sys.meta_path를 사용하는 메타 경로 파인더와 sys.path_hooks를 사용하는 경로 항목 파인더가 있습니다.

여기서는 메타 경로 파인더를 살펴보겠습니다.


메타 경로 파인더


메타 경로 파인더(meta path finder)는 표준 .py 파일뿐만 아니라 사용자 지정 객체를 로드할 수 있는 객체입니다.

메타 경로 파인더 객체는 로더 객체를 반환하는 find_module(fullname, path=None) 메서드를 호출해야 합니다.

반환할 로더 객체에는 소스 파일에서 모듈을 로드하는 load_module(fullname) 메서드도 있어야 합니다.


코드를 봅시다.

먼저 Hy 모듈 로더 객체 코드부터 보겠습니다.


import os
import sys


class MetaLoader(object):
def __init__(self, path):
self.path = path

def is_package(self, fullname):
dirpath = '/'.join(fullname.split('.'))
for pth in sys.path:
pth = os.path.abspath(pth) # 절대경로 얻기
composed_path = f'{pth}/{dirpath}/__init__.hy' # 문서의 경로 파악
if os.path.exists(composed_path): # 만일 해당 경로에 __init__.hy가 있으면 package
return True
return False # 없으면 package가 아니다

def load_module(self, fullname):
if fullname in sys.modules: # 만일 불러온 적 있는 모듈이라면 바로 반환
return sys.modules[fullname]
if not self.path: # 경로가 없으면 return
return

sys.modules[fullname] = None
mod = import_file_to_module(fullname, self.path)

ispkg = self.is_package(fullname)

mod.__file__ = self.path
mod.__loader__ = self
mod.__name__ = fullname

if ispkg:
mod.__path__ = []
mod.__package__ = fullname
else:
mod.__package__ = fullname.rpartition('.')[0]

sys.modules[fullname] = mod
return mod


여기서 import_file_to_module 함수는 .hy 소스 파일을 읽고, 파이썬 코드로 컴파일하고,

파이썬 모듈 객체를 반환합니다. (내장함수가 아니며, 여기서 구현하지 않았습니다. 역할만 인지합시다!)


다음으로 사용자 지정 메타 경로 파인더를 사용하여 .py 대신 .hy로 끝나는 소스 파일을

가져올 수 있도록 하는 방법을 보겠습니다.


class MetaImporter(object):
def find_on_path(self, fullname):
fls = ['%s/__init__.hy', '%s.hy']
dirpath = '/'.join(fullname.split('.'))

for pth in sys.path:
pth = os.path.abspath(pth) # 해당 모듈이 있을 가능성이 있는 절대경로 찾음
for fp in fls:
composed_path = fp % (f'{pth}/{dirpath}')
if os.path.exists(composed_path): # 모듈이 있을 경우 path 반환
return composed_path

def find_module(self, fullname, path=None):
path = self.find_on_path(fullname)
if path:
return MetaLoader(path)

sys.meta_path.append(MetaImporter())


find_on_path 메서드에서 sys.path를 다 순회하는 이유는 어느 path에 모듈이 있을지 모르기 때문입니다.

sys.meta_path에 MetaImporter를 append해주면 끝입니다.


이상으로 메타 경로 파인더를 이용해 사용자 지정 객체를 불러오는 방법을 살펴보았습니다.

큰 골자는 MetaImporter에서 모듈이 있는지를 파악하고, find_module 메서드에서 모듈 로더 객체를 반환하고, 

모듈 로더 객체에서 load_module 메서드를 호출하고, 

마지막으로 sys.meta_path 리스트에 MetaImporter를 추가해주면 됩니다.


모듈 불러오기는 기본적인 내용인데 쉽지 않네요..

그래도 언젠가 유용하게 사용될 기술이니 기록해둡니다.

python    26   view  844
Log in and leave a comment
fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

xfXkNjHt

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1 OR 2+676-676-1=0+0+0+1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1 OR 3+676-676-1=0+0+0+1

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*if(now()=sysdate(),sleep(15),0)

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

0'XOR(
*if(now()=sysdate(),sleep(15),0))XOR'Z

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

0"XOR(
*if(now()=sysdate(),sleep(15),0))XOR"Z

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1; waitfor delay '0:0:15' --

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1); waitfor delay '0:0:15' --

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1 waitfor delay '0:0:15' --

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

6xZXpz4u'; waitfor delay '0:0:15' --

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1 OR 824=(SELECT 824 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1) OR 969=(SELECT 969 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

-1)) OR 406=(SELECT 406 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

zHnVpalc' OR 82=(SELECT 82 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

byFdLz2s') OR 535=(SELECT 535 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

Gc43zRnR')) OR 952=(SELECT 952 FROM PG_SLEEP(15))--

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

'"

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

����%2527%2522\'\"

Updated: Feb. 22, 2025, 5:32 p.m.


fnfOzvSR
fnfOzvSR   Feb. 22, 2025, 5:32 p.m.

@@KVNMX

Updated: Feb. 22, 2025, 5:32 p.m.