# Python
###### tags: `Python` `atom`
### 零、參考
[Installing Packages](https://packaging.python.org/tutorials/installing-packages/)
[Pipenv & Virtual Environments](https://docs.python-guide.org/dev/virtualenvs/)
[How to Install Pip on Ubuntu 18.04](https://linuxize.com/post/how-to-install-pip-on-ubuntu-18.04/)
[Install Python3 on Ubuntu 18.04 and Set Up a Virtual Programming Environment](https://vitux.com/install-python3-on-ubuntu-and-set-up-a-virtual-programming-environment/)
### 一、安裝 Python
目的: 環境安裝主要是在OS上安裝 Python,IDE環境,和虛擬目錄。
使用
- Python 3.6.8 - Dec. 24, 2018,
- Ubuntu 18.0.4
#### 二、安裝 virtualenv
##### 1. 使用 pip 指令安裝
安裝``pip`` for Python3:
```
$ sudo apt-get update
$ sudo apt install python3-pip
$ pip3 -V
```
##### 2. virtualenv
###### 2.1 安裝
```
$ pip3 install virtualenv
```
測試安裝是否成功?
```
$ virtualenv --version
```
or
```
$ sudo apt install -y python3-venv
```
###### 2.2 建立 venv工作目錄
假設已在一個資料夾名為``project_folder``
```
$ cd project_folder
```
假設虛擬工作目錄為 ``venv``
```
$ virtualenv venv
```
or
```
python -m venv venv
```
###### 2.3 進入venv模式
```
source venv/bin/activate
```
```
.\venv\Scripts\activate
```
成功後,會看見
```
(venv)Your-Computer:project_folder UserName$
```
之後就可以在專屬環境下安裝會使用到的套件
```
pip install requests
```
```
pip install --upgrade requests
```
指定版本
```
pip3 install 'SQLAlchemy==1.3.20'
pip3 install -Iv SQLAlchemy = 1.3.20
pip install -v pyodbc==4.0.32
```
安裝 ``requirements.txt`` 中的套件
```
pip install -r requirements.txt
```
輸出套件到 ``requirements.txt``
```
pip freeze > requirements.txt
```
###### 2.4 離閈venv模式
若用完 venv 要關掉
```
$ deactivate
```
想刪掉虛擬環境,只要直接把資料夾刪除;例如:
```
$ rm -rf project_folder
```
---
# Project structure & import
假設 我的 python project 名稱為 ``my_project``,
然後有兩個子資料夾: ``common`` 與 ``app``
在 ``common`` 開發共用、可重覆使用的模組
在 ``app`` 開發執行程序 ``*.py``
初始架構如下
```
my_project/
├── common/
│ └── shared_module.py
└── app/
└── main_app_script.py
```
## 增加 ``__init__.py`` 檔案
為了能在 ``app`` 底下的 ``*.py`` 能夠 import ``common`` 底下的 classes/ functions
要在各自的目錄底下新增空白內容的 ``__init__.py``
```
my_project/
├── common/
│ ├── __init__.py <- Add this file
│ └── shared_module.py
└── app/
├── __init__.py <- Add this file (optional, but good practice if 'app' will have its own imports)
└── main_app_script.py
```
## Import
假設``shared_module.py`` 的內容如下
```
def say_hello(name):
return f"Hello, {name} from shared_module!"
class MySharedClass:
def __init__(self, value):
self.value = value
def get_value(self):
return self.value * 2
```
此時在``main_app_script.py`` 中的 import 方式有兩種
### Option 1: Absolute import (絕對)
recommended when running from the project root
(以目前 ``my_project`` 資料夾結構, 建議)
```
from common.shared_module import say_hello, MySharedClass
```
### Option 2: Relative import (相對)
if ``main_app_script.py`` were in a ``sub-sub-folder`` of ``app``
(若 ``main_app_script.py`` 是在 ``app`` 的子資料夾)
```
from ..common.shared_module import say_hello, MySharedClass # Not applicable here, just for illustration
```
## Execution
```
python -m app.main_app_script
```
optional
```
cd my_project
python app/main_app_script.py
```
---
# Q1
You are python expert.
In a project folder (e.g., ``my_project``), there are two sub-folders, ``dev_a`` and ``dev_b``.
I define some classes and function in a python script file that is under folder ``dev_a``.
now there is another python script under the ``dev_b``
where i like to import classes / function under ``dev_a``.
how can i do?
## A1
Here's how to properly import between subdirectories in Python:
Project Structure
```
my_project/
├── __init__.py
├── dev_a/
│ ├── __init__.py
│ └── module_a.py
└── dev_b/
├── __init__.py
└── module_b.py
```
### Solution 1: Absolute Import (Recommended)
First make your project a proper Python package by creating these empty files:
* ``my_project/__init__.py``
* ``my_project/dev_a/__init__.py``
* ``my_project/dev_b/__init__.py``
In ``dev_b/module_b.py``:
```
from my_project.dev_a.module_a import MyClass, my_function
# Usage
obj = MyClass()
result = my_function()
```
### Solution 2: Relative Import (For sibling directories)
我選擇這個
In ``dev_b/module_b.py``:
```
from ..dev_a.module_a import MyClass # Double dot for parent directory
# Usage
obj = MyClass()
```
### Key Points:
#### Package Structure:
* The ``__init__.py`` files (even empty) make directories recognized as Python packages
* Required for proper imports between directories
#### Execution Context:
Run your code from the project root directory:
```
cd my_project
python -m dev_b.module_b
```
#### Best Practices:
* Use absolute imports (Solution 1) for clarity
* Consider creating a ``setup.py`` for proper package installation
* For complex projects, use Python path management tools like:
* ``poetry``
* ``pipenv``
* ``Standard ``venv`` with proper ``PYTHONPATH`` setup
### Common Errors & Fixes:
#### 1. ModuleNotFoundError:
```
# If you see this error:
# "No module named 'my_project'"
# Fix: Install your package in development mode
# From project root:
pip install -e .
```
#### 2. ImportError (relative imports):
```
# If you see:
# "ImportError: attempted relative import with no known parent package"
# Fix: Run using module syntax instead of direct file execution
python -m dev_b.module_b # Instead of python dev_b/module_b.py
```
#### 3. Circular Imports:
* __Avoid mutual imports__ between modules
* Use type hints with ``from __future__ import annotations`` if needed
For production projects, I recommend using Solution 1
with proper package installation through a ``setup.py`` file.
---
## Python folder / package Structure
### Key Points:
Directory structure should look like this:
```
复制
Proj_Srcs_python/
└── KofIvAppsScript/
├── __init__.py
├── py_common/
│ ├── __init__.py
│ ├── exceptions.py
│ ├── ...
└── invoice_generator/
├── __init__.py
└── pdf_extraction_01.py
```
#### Run script
__Never run scripts from inner directories -
always execute from project root__:
Wrong way:
```
PS D:\Proj_Srcs_python> cd .\KofIvAppsScript\
PS D:\Proj_Srcs_python\KofIvAppsScript> cd .\invoice_generator\
PS D:\Proj_Srcs_python\KofIvAppsScript\invoice_generator> python .\pdf_extraction_01.py
```
Correct way:
```
cd D:\Proj_Srcs_python
PS D:\Proj_Srcs_python> python -m KofIvAppsScript.invoice_generator.pdf_extraction_01
```
#### If using VSCode/PyCharm:
* Set ``Proj_Srcs_python`` as "Sources Root"
* Mark ``KofIvAppsScript`` as "Python Package"
---
* [A Beginner's Python Tutorial](https://en.wikibooks.org/wiki/A_Beginner%27s_Python_Tutorial)
* [Python Tutorial](https://www.w3schools.com/python/default.asp)
* [Python Programming Tips #2](http://www.qtrac.eu/pyclassmulti.html)
不要使用空白,而要使用tab來縮排
Ubuntu:
Lingo
Object-oriented programming has a set of lingo that is associated with it.
It's about time that we have this all cleared up:
- when we first describe a class, we are defining it (like with functions)
- the ability to group similar functions and variables together is called ++encapsulation++
- the word ++class++ can be used when describing the code
where the class is defined (like how a function is defined),
and it can also refer to an instance of that class -
this can get confusing, so make sure you know in which form we are talking about classes
- a variable inside a class is known as an 'attribute'
- a function inside a class is known as a 'method'
- a class is in the same category of things as variables, lists, dictionaries, etc.
That is, they are objects
- a class is known as a 'data structure' - it holds data, and the methods to process that data.
______________________________________
code - Reuse - Module
Last lesson we covered the killer topic of Classes.
As you can remember,
classes are neat combinations of variables and functions in a nice, neat package.
Programming lingo calls this feature encapsulation,
but regardless of what it is called,
it's a really cool feature for keeping things together
so the code can be used in many instances in lots of places.
Of course, you've got to ask, "how do I get my classes to many places, in many programs?".
The answer is to put them into a module, to be imported into other programs.
Module? What's a Module?
A module is a Python file that (generally)
has only definitions of variables, functions, and classes.
For example, a module might look like this:
```
Code Example 1 - moduletest.py
### EXAMPLE PYTHON MODULE
# Define some variables:
numberone = 1
ageofqueen = 78
# define some functions
def printhello():
print "hello"
def timesfour(input):
print input * 4
# define a class
class Piano:
def __init__(self):
self.type = input("What type of piano? ")
self.height = input("What height (in feet)? ")
self.price = input("How much did it cost? ")
self.age = input("How old is it (in years)? ")
def printdetails(self):
print "This piano is a/an " + self.height + " foot",
print self.type, "piano, " + self.age, "years old and costing\
" + self.price + " dollars."
```
As you see, a module looks pretty much like your normal Python program.
So what do we do with a module?
We import bits of it (or all of it) into other programs.
To import all the variables, functions and classes
from ``moduletest.py`` into another program you are writing,
we use the ``import`` operator.
For example, to ``import moduletest.py`` into your main program, you would have this:
```
Code Example 2 - mainprogram.py
### mainprogam.py
### IMPORTS ANOTHER MODULE
import moduletest
```
小心不同目錄的問題!!
This assumes that the module is in the same directory as ``mainprogram.py``,
or is a default module that comes with python.
You leave out the ``.py`` at the end of the file - it is ignored.
You normally put all import statements at the beginning of the python file,
but technically they can be anywhere.
In order to use the items of the module in your main program,
you use the following:
---
# Windows venv
## Use PyCharm
* [Configure a virtual environment](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
* [Configure a Python interpreter](https://www.jetbrains.com/help/pycharm/configuring-python-interpreter.html#interpreter)




## Start venv in PowerShell
* [HOW TO ACTIVATE VIRTUAL ENVIRONMENT IN POWERSHELL?](https://poanchen.github.io/blog/2020/10/23/how-to-activate-virtual-environment-in-powershell)
```
.\venv\Scripts\activate
```
```
deactivate
```

``.ps:``
```
Set-Location "D:\Python_venv\py36_google_sheets\"
.\venv\Scripts\Activate.ps1
python "D:\Python_venv\py36_google_sheets\sunlike_task.py"
deactivate
exit
```
---
# [What is the difference between pyenv and virtualenv?](https://medium.com/@lgryffin/what-is-the-difference-between-pyenv-and-virtualenv-4930904a362e)
It’s a good question. I was having trouble identifying
the exact delineation of tasks between the tools,
so I broke it down as concretely as possible.
I have an OSX system default __Python 2.7__ install in ``/usr/lib/python2.7``.
I have a Homebrew-installed __Python 3.7__ at ``/Users/lbryan/Library/Python``.
Then I have a Homebrew-installed version of __pyenv__ at ``/usr/local/bin/pyenv``.
My ``PATH`` variable (the variable that lists directories
where executables can be found, separated by colon) looks like this:
```
$ echo $PATH
/Users/lbryan/.pyenv/shims:/Users/lbryan/Library/Python/3.7/bin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
__pyenv uses 'shim' scripts
to act as a little Python version traffic controller__,
— notice that the __pyenv shim is first in the list of paths
in my ``PATH`` variable. [This article](https://mungingdata.com/python/how-pyenv-works-shims/) goes into some more detail
on __how pyenv and shims work__,
and __what environment variables pyenv uses__,
I found it really helpful.
* [Deep dive into how pyenv actually works by leveraging the shim design pattern](https://mungingdata.com/python/how-pyenv-works-shims/)
But…__where do ``pip``-installed packages…go
when they’re installed outside of a virtual environment
when I’m using pyenv__? Note that __``pip`` is also redirected via a ``pyenv shim``__:
```
$ which pip
/Users/lbryan/.pyenv/shims/pip
```
I’ve only recently started using pyenv, and
I’ve __previously installed a fair number of packages
to my global Python 3.7 environment__, so that
I can quickly open an iPython REPL and test something out,
when I’m not concerned about exact versions
(which is a bit sloppy, but it works for when I need to
understand how something works outside of code
I plan to commit, or for analyzing data on the fly).
Before I installed pyenv, ``pip``-installed packages like __pandas__
went to ``/usr/local/lib/python3.7/site-packages``.
Sure enough, if I ask ``pip`` about a library
I already have installed, I see that path:
```
$ pip show pandas
Name: pandas
Version: 0.25.3
Summary: Powerful data structures for data analysis, time series, and statistics
Location: /usr/local/lib/python3.7/site-packages
Requires: python-dateutil, pytz, numpy
```
__I was confused about something here__.
Why are libraries being installed to the above path,
__if I’ve been using Python 3.8.5 as my pyenv global version?__
I tried installing a new library via ``pip``,
and __it ended up in the 3.7 site packages also__.
Why? Turns out there was __a ``.python-version`` file
already installed in my working directory.
That file is used by pyenv to direct the shim
to the version of Python you want to use__.
Here’s the contents of that file:
```
$ cat .python-version
system
```
``pyenv global`` 會使用 ``.python-version``
- 使用作者 Global (3.7 的 pip)
__pyenv was working as expected, just not as I expected__.
Instead of directing ``pip`` to the global version
I currently had set via ``pyenv global``,
it was using my 3.7 system install.
I edited the file to show 3.8.5 , and then when I ``pip install pandas``,
pandas is now installed where I expect:
```
$ pip show pandas
Name: pandas
Version: 1.1.2
Summary: Powerful data structures for data analysis, time series, and statistics
Location: /Users/lbryan/.pyenv/versions/3.8.5/lib/python3.8/site-packages
Requires: numpy, pytz, python-dateutil
```
Small mystery solved.
So how do virtual environments fit in?
Python is a bit of a nightmare in production.
My team doesn’t really write traditional ‘production’ code —
we do a fair amount of data analysis on the fly,
and need codebases that are really flexible,
since our deliverables are machine learning models,
where data inputs and data processing
can vary significantly between projects.
If I check in a script, used to create an artifact,
say a matrix that’s used to project vectors
from a high dimension to a lower dimension,
and I want to run the script again months later
and produce the same result,
I need to know that __my environment variables, Python version,
and Python libraries (among other things) haven’t changed__.
This is harder than it seems like it should be.
__That script that I checked in now
needs to be packaged up into a library
that the rest of the team can use, that pins library versions,
and doesn’t rely on any particular system state__,
to whatever degree possible.
__Pyenv doesn’t solve these problems__,
it just __makes switching between Python versions easier__,
__by intercepting shell commands like ``python3`` or ``pip``
and executing them from the correct version of Python__.
If the pyenv Python packages get updated, and my script no longer runs, or arguably worse, silently produces different output, I don’t have any way of recreating the state that my script ran in before. A virtual environment created from a tool like venv or virtualenv can help solve some of those problems.
pyenv 可以切換不同 Python 版本
__Running ``pyenv local 3.8.5`` in a directory creates a ``.python-version`` file__,
that contains the text ``3.8.5``.
This file is used to __direct the shim to the correct python version__
when the user executes a command like ``pip`` or ``python``
from that directory. Now that I want to create a virtual environment.
There are a few options: the Python 3 standard library includes ``venv``,
typically run with ``python -m venv ENV_DIR_NAME``.
Another very popular option is ``virtualenv``,
which isn’t part of the standard library,
but is more fully featured than ``venv`` (see this [StackOverflow post](https://stackoverflow.com/questions/41573587/what-is-the-difference-between-venv-pyvenv-pyenv-virtualenv-virtualenvwrappe)).
Confusingly, __pyenv also has a side-project called pyenv-virtualenv__ .
My team uses ``virtualenv`` for packaged projects,
managed via a tool called [``tox``](https://tox.readthedocs.io/en/latest/).
``pyenv local 3.8.5`` 在所在資料夾建立``.python-version``,
Since my pyenv-Python 3.8.5 install doesn’t include ``virtualenv``
in it’s site-packages directory
(on my computer at ``~/.pyenv/versions/3.8.5/site-packages``),
I need to install the package via ``pip``. Once that’s done,
I can create a new virtual environment with ``virtualenv env``.
If I want to install a package to this new environment, say __numpy__,
then I need to install it using the ``pip`` package
__that is installed in my virtual environment,
not the ``pip`` that is installed to the Python 3.8.5 version__
that I used to create the environment.
This is typically accomplished by ‘activating’ the environment,
but I can also just find the ``pip`` executable in the ``env`` directory:
```
$ env/bin/pip install numpy
```
I should now see __numpy__ installed to my site-packages directory in ``env``:
```
$ ls env/lib/python3.8/site-packages/ |grep numpy
numpy
numpy-1.19.2.dist-info
```
Success!
I like using the contents of the ``env`` directory
rather than activating the environment
because it’s helped me concretize attribution.
I’m also somewhat paranoid about checking attribution
with shell commands like ``which`` (e.g. ``which pip``),
because I’ve made a lot of mistakes in the past.
paranoid (a)
worrying that people do not like you and are trying to harm you, although you have no proof of this
e.g., paranoid about: They’re obviously paranoid about somebody copying their products.
The environment we created __[contains a separate version of Python](https://virtualenv.pypa.io/en/latest/user_guide.html)__
from the pyenv Python install that we started with. We bootstrapped — we used Python to install even more Python. A lot of the pain I’ve experienced working with Python is because of bootstrapping, or not having a clear mental model of command attribution, which package installed from where, using a system Python install instead of the one in the virtual environment that I intended to use, running a script with the wrong version of Python, on and on.
Hope this helps!
看了這篇文章, pyenv 只是方便讓我們在 shell 下,
輸入 python, pip 時可以指定想要的版本,
但使用 ``venv`` 資料夾可以搬入想要的 Python 版本,
和指定的 modules / libraries, 將要用到的東西打包在一起, 與外面隔離!!
---
# Uninstall On Mac OS
## Q - 2025/12/21
I downloaded a new version of python ``.pkg`` from the official site.
I simply install the version.
Now, in the ``/Library/Frameworks/Python.framework/Versions/``,
there are ``3.13`` and ``3.14`` folders
Should i remove the previous one?
## A - From Gemini
### To answer your question:
**No, you do not need to remove the previous version (3.13)**.
In fact, keeping both is common practice for developers.
### If you still want to remove 3.13 to save space
If you are sure you don't need it,
you can remove it manually, but do not just drag the folder to the Trash.
You must use the Terminal to clean it up properly:
#### Delete the Framework folder:
```Bash
sudo rm -rf /Library/Frameworks/Python.framework/Versions/3.13
```
#### Delete the Application folder:
```Bash
sudo rm -rf "/Applications/Python 3.13"
```
#### Clean up the "Links" (optional but recommended):
These are the tiny shortcut files in your system that point to 3.13.
You can find them by running:
```Bash
ls -l /usr/local/bin | grep 3.13
```
Then remove them using ``sudo rm``.
my case:
```
ls -l /usr/local/bin | grep 3.13
lrwxr-xr-x 1 root wheel 71 7 9 23:13 idle3.13 -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/idle3.13
lrwxrwxr-x 1 root admin 70 7 9 23:13 pip3.13 -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/pip3.13
lrwxr-xr-x 1 root wheel 72 7 9 23:13 pydoc3.13 -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/pydoc3.13
lrwxr-xr-x 1 root wheel 73 7 9 23:13 python3.13 -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/python3.13
lrwxr-xr-x 1 root wheel 80 7 9 23:13 python3.13-config -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/python3.13-config
lrwxr-xr-x 1 root wheel 81 7 9 23:13 python3.13-intel64 -> ../../../Library/Frameworks/Python.framework/Versions/3.13/bin/python3.13-intel64
lrwxr-xr-x 1 root wheel 75 7 9 23:13 python3.13t -> ../../../Library/Frameworks/PythonT.framework/Versions/3.13/bin/python3.13t
lrwxr-xr-x 1 root wheel 82 7 9 23:13 python3.13t-config -> ../../../Library/Frameworks/PythonT.framework/Versions/3.13/bin/python3.13t-config
lrwxr-xr-x 1 root wheel 83 7 9 23:13 python3.13t-intel64 -> ../../../Library/Frameworks/PythonT.framework/Versions/3.13/bin/python3.13t-intel64
```
then ``sudo rm /usr/local/bin/*3.13*``
then run ``ls -l /usr/local/bin | grep 3.13`` again, the result should be empty!!
#### Important Warning
Never touch any Python folders located in ``/System/Library/`` or ``/usr/bin/python3``.
These are required by macOS to run your computer;
deleting them can break your operating system.