# PyO3를 이용한 Rust와 Python의 가변 데이터 공유 기법

> Clean Markdown view of GeekNews topic #22949. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=22949](https://news.hada.io/topic?id=22949)
- GeekNews Markdown: [https://news.hada.io/topic/22949.md](https://news.hada.io/topic/22949.md)
- Type: news
- Author: [darjeeling](https://news.hada.io/@darjeeling)
- Published: 2025-09-07T18:41:59+09:00
- Updated: 2025-09-07T18:41:59+09:00
- Original source: [blog.lilyf.org](https://blog.lilyf.org/posts/python-mutable-reference/)
- Points: 4
- Comments: 0

## Topic Body

##### **결론 (Conclusion)**  
  
PyO3가 Rust의 라이프타임(lifetime)을 사용하는 구조체를 직접 Python에 노출하지 못하는 것은 처음에는 한계처럼 보일 수 있습니다. 하지만 Rust 표준 라이브러리와 PyO3는 이러한 한계를 극복할 강력한 도구들을 제공합니다. `std::mem::take`와 `std::mem::replace`는 변경 가능한 참조(mutable reference)와 소유된 값(owned value)을 능숙하게 다룰 수 있게 해주며, `Arc`와 `Mutex`는 공유되는 변경 가능한 데이터를 Python에 노출하는 데 매우 유용합니다. 특히 PyO3의 `MutexExt`는 Python과 함께 뮤텍스를 사용할 때 데드락을 방지하는 필수적인 도구입니다.  
  
---  
  
##### **주요 내용 요약**  
  
이 문서는 Django의 템플릿 언어를 Rust로 재구현하는 프로젝트에서 Rust와 Python 간에 변경 가능한(mutable) 데이터를 공유하면서 마주친 기술적 문제와 그 해결 과정을 단계별로 설명합니다.  
  
* **배경**: Django 템플릿 언어는 `context`라는 객체를 사용하여 템플릿에 동적 데이터를 제공합니다. 프로젝트의 Rust 구현체에서는 이 `context`를 Rust 구조체로 정의했으며, 템플릿 태그를 렌더링할 때 변경 가능한 참조(`&mut Context`)로 전달해야 합니다.  
  
* **초기 문제**: Rust 코드의 변경 가능한 참조(`&mut Context`)를 커스텀 태그 실행을 위해 Python 함수로 전달해야 합니다. 하지만 Python은 Rust의 라이프타임을 이해하지 못하며, Rust-Python 연동 라이브러리인 PyO3는 소유권이 있는 값(owned value)을 요구하기 때문에 참조를 직접 전달하면 컴파일 에러가 발생합니다.  
  
* **해결 과정**:  
    1.  **소유권 문제 해결**: `std::mem::take`를 사용하여 `&mut Context`에서 소유권을 잠시 가져와 Python에 전달 가능한 소유된 `Context` 객체를 생성합니다. Python 코드 실행 후에는 `std::mem::replace`를 사용하여 처리된 `Context`를 다시 원래의 참조 위치로 돌려놓으려 시도합니다.  
    2.  **'Moved Value' 에러 해결**: 하지만 이 과정에서 `Context` 객체가 Python 함수로 이동(move)된 후 다시 사용하려 할 때 "use of moved value" 컴파일 에러가 발생합니다. 이 문제를 해결하기 위해 `Arc`(Atomic Reference Count)를 도입하여 `Context`를 감쌉니다. 이를 통해 소유권을 옮기지 않고도 Python에 복제된 참조(`clone`)를 전달할 수 있습니다.  
    3.  **Python의 참조 유지 시 처리**: Python이 `Context`에 대한 참조를 계속 유지할 경우 `Arc::try_unwrap`을 통한 소유권 회수가 실패할 수 있습니다. 이 경우, `Context` 내부 데이터를 깊은 복사(deep clone)하는 `clone_ref`와 같은 fallback 메소드를 구현하여 데이터를 복제합니다.  
    4.  **Python에서의 데이터 변경 허용**: 최종적으로 Python 코드가 `Context`를 읽기만 하는 것이 아니라 변경도 할 수 있도록 `Mutex`를 도입합니다. `Arc<Mutex&lt;Context&gt;>` 구조를 사용하여 여러 스레드에서 안전하게 데이터에 접근하고 수정할 수 있도록 보장합니다. 이때 Python 인터프리터와의 데드락을 방지하기 위해 PyO3가 제공하는 `MutexExt`의 `lock_py_attached` 메소드를 사용합니다.

## Comments



_No public comments on this page._
