Table of contents
args & kwargs
(2022-08-05)
-
*args:表示接受任意个数的 Positional arguments,然后存放入一个元组中;传参时 位置 要对应,例如1 2 3 4 5def fun (*args) print(args) fun('fruit', 'animal', 'human') >>> 'fruit','animal','human' -
**kwargs:表示接受任意长的 Keywords arguments,然后存放入一个字典中;传参时要对应 key,例如1 2 3 4 5def fun(**kwargs): for key, value in kwargs.items(): print("%s:%s" % (key,value) fun(a=1,b=2,c=3)会输出 a=1 b=2 c=3
Positional args and keywords args
|
|
注解 annotation
类型不匹配警告
|
|
|
|
|
|
|
|
|
|
|
|
Class Variable & Instance Variable
|
|
- All instances of the class have access to
class_var, as well as the class itself. - If class_var is mutable type, like list, class_var will influence on all instances.
Reference: Python Class Attributes: An Overly Thorough Guide
@classmethod
-
classmethod can only be called through the class name instead through an object instantiated from the class, because it gets passed the
clsas the argument.- Similarly,
selfmeans a method belongs to an instance, and can only be called via instance.
- Similarly,
-
classmethod can access the class variables.
-
classmethod usually is used for instantiating an object with a set of specific arguments rather through
__init__().1 2 3 4 5 6 7 8 9 10 11 12 13class PositionalEncoding(torch.nn.Module): def __init__(self, ..): # instance method ... @classmethod def from_conf(cls, conf, d_in=3): # conf: 'default.conf'.model.code{} # PyHocon construction return cls( conf.get_int("num_freqs", 6), d_in, conf.get_float("freq_factor", np.pi), conf.get_bool("include_input", True), )Code snippest from pixel-nerf
Ref: An essential guide to Python class methods and when to use them
@staticmethod
@staticmethod in Python - AskPython
- No need to pass an instance (
self) or class (cls) to it as the first argument. - So it can be called both by the class name and an instance.
- Can be overridden by children class.
__name__
当一个 py 文件被直接执行时,__name__ 被设置为 '__main__',如果是被 impot,则它的 __name__ 被设置为它的文件名(不包括后缀),并且被导入时会执行顶层的代码(不包括 function, class)
__init__
References:
Notes:
(2025-03-26)
- To differenciate two scenarios:
import <a file>andimport <a package>r1-Hucci
__file__
-
(2024-02-28) Ref: GfG
The file path of the function’s definition
1 2 3# Hello.py def HelloWorld(): print("This is Hello.py")Call that module in another file:
1 2 3 4 5 6 7 8 9 10 11# GFK.py import Hello import os Hello.HelloWorld() print(Hello.__file__) print(f'GFK.py\'s __file__: {__file__}') print(os.path.join(os.path.dirname(os.path.abspath(__file__)), "third_party/glm/"))Output of
python GFK.py1 2 3 4This is Hello.py /home/yi/Downloads/ipynb_test/test_file_/Hello.py GFK.py's __file__: GFK.py /home/yi/Downloads/ipynb_test/test_file_/third_party/glm/
Built-in functions
-
dir(object)returns a list of the names of attributes and methods of any kind of object, e.g., module, class, instance. No values are stored. -
vars(object)returns a dict:object.__dict__containing changeable attributes.vars()acts likelocals(): a dict of local variables for read.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20class person: name = "jack" dir(person) # A list, len = 27 person.__dir__ # A method vars(person) # same as person.__dict__, len=5 # instance student = person() setattr(student, 'age', 14) vars(student) # out: {'age': 14} dir(student) # a list of attr and methods of the object set(student.__dir__()) - set(dir(person)) # out: {'age'} set(student.__dir__()) == set(dir(student)) # True set(dir(student)) == set(person.__dir__(student)) # True set(dir(student)) - set(person.__dir__(person)) # {'__weakref__', 'age', 'name'} set(person.__dir__(person)) - set(dir(student)) # {'__abstractmethods__', '__base__', '__bases__', ...
[::-1] flip image
|
|
表达式内赋值
PEP 572, Python 3.8+, 类似 n := xxx
比如,有一个字符串数组,想去掉每个字符串里的空格和空字符串
|
|
两行写一行:
arr = [ y for x in arr if (y := x.strip)) ]
团队开发最好还是用易懂的写法。 1_00_00什么意思?x:=y?Python里面的几个有趣特性
Index value from dict
Get value by giving index from a dictionary
Accessing dictionary value by index in python
Python Dictionaries are Ordered from python 3.7 6, so the index can be used like:
value_at_index = list(dic.values())[index]
Make one-hot matrix
Convert a vector to one-hot matrix
Convert array of indices to one-hot encoded array in NumPy - StackOvf
|
|
if/else in a list
comprehension SO
Flatten a list of list
Python - Flatten a list of lists to a single list (Dead link now)
- Concatenate list of tensor:
torch.stack()first, thenreshape
Redirect print content
(2023-08-08)
Redirect the standard output (print stream) to a file using the sys module.
|
|
argparse
(2023-08-28)
-
action="store_true", this option is True when this argument appears in the command -
nargs=+, this argument at least be assigned with 1 value. Similarly,nargs=3, the argument must be assigned with 3 values.Argparse: how to handle variable number of arguments (nargs=’*’) - SO
1parser.add_argument('--img_wh', nargs="+", type=int, default=[1152, 864])The command line:
python eval.py --img_wh 640 512. Theargsin vscode “launch.json”:"args": ["--img_wh", "1152", "864",] -
Update Dict attributes (packge: mmcv)
1 2 3 4 5 6 7from mmcv import DictAction parser = argparse.ArgumentParser(description='Train a recognizer') parser.add_argument('--cfg-options', nargs='+', action=DictAction, default={}, help='override some settings in the used config, the key-value pair ' 'in xxx=yyy format will be merged into config file. For example, ' "'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'")Example in launch.json of adapt-image-models:
1 2 3 4"args": [ "--cfg-options", "model.backbone.pretrained=openaiclip", "work_dir=work_dirs_vit/diving48/debug", ] -
Set choices:
1 2 3 4 5parser.add_argument( '--launcher', choices=['none', 'pytorch', 'slurm', 'mpi'], default='none', help='job launcher')
Accept a dict
(2023-08-31)
Accepting a dictionary as an argument with argparse and python (duplicate) -SO
argparse don’t have a type of dict, there’re 2 workarounds:
-
Set
type=str, then usejson.loads()to parse: -
Set
type=json.loads:1 2 3 4 5import json parser.add_argument('-d', '--my-dict', type=json.loads) args = parse.parse_args() mydict = args.my_dict # Will return a dictionary
-
The
DictActionof mmcv will only parse the top-level as a dict (key-value), but if the value passed is a dict too, it’ll be parsed as a string.1 2 3 4 5 6 7 8 9 10"args": [ "--cfg-options", "model.backbone.num_frames=3", // "train_pipeline[1].clip_len=3", // Cannot identify [1] // "dict(train_pipeline={'1': dict(clip_len=3)})", // Error: has to 2 params, but got 1. // "train_pipeline= {\"1\": {\"clip_len\": \"3\"}}" // The value will be parsed as a string, which will override the whole previous dict. ]
Access a dict
-
myDict.update({'aKey': "newVal"})ormyDict.update(aKey='newVal') -
myDict.get('aKey', retVal) -
myDict.setdefault('aKey', 'defVal'): if'aKey'doesn’t exist, it will be inserted with the default valuedefVal. -
myDict.copy()ornewDict = dir(myDict)are shallow copy: when change the no-primitive data (such as list, nested data), the orignal dict will also change, because it only duplicate the top-level data, while the low-level data is referenced to the original data. Copy a Python Dictionary: A Complete Guide • datagy -
myDict.pop('aKey')will return and remove an item. -
Delete items from dictionary while iterating Have to iterate the dict twice, the 1st round collects the keys to be deleted, and the 2nd round del those items.
logging
|
|
Output: INFO:__main__:This is an info message
tqdm
(2023-10-20)
DDG with searching “avoid writting tqdm bar into the log file”
-
Use tqdm to iterate the outer loop and print in the inner loop. How can I make the tqdm progress bar be printed less frequently in the log file?
1 2 3for outer in tqdm(range(0, 1e5, 1e4)): for inner in range(1e4): print(outer+inner) -
Output tqdm to a null device, and print/log the status bar after desired steps. python - Making tqdm write to log files - Stack Overflow
1 2 3 4tqdm_bar = tqdm(range(20), file=open(os.devnull, 'w')) for i in tqdm_bar: if tqdm_bar.n % 5 ==0: print(str(tqdm_bar)) -
Redirecting console logging to tqdm.write(), leaving other logging handlers (e.g. log files) unaffected. tqdm.contrib.logging - Docs
1 2 3 4 5 6 7 8 9 10 11 12 13import logging from tqdm import trange from tqdm.contrib.logging import logging_redirect_tqdm LOG = logging.getLogger(__name__) if __name__ == '__main__': logging.basicConfig(level=logging.INFO) with logging_redirect_tqdm(): for i in trange(9): if i == 4: LOG.info("console logging redirected to `tqdm.write()`") # logging restored
-
tqdm output to stderr, which is not in sync with stdout. So only redict the stdout (
print) to file:python test.py > output.logHow to “flush” tqdm progress bar explicitly?
Found in Google
-
Monitor log file in real-time:
tail -f output.log. reddit -
Disable tqdm bar
-
Presetting argument. Inspired by the comment of this answer of Why is tqdm printing to a newline instead of updating the same line?; Searched by DDG with searching “tqdm leave”
1 2 3 4 5from functools import partial from tqdm import tqdm tqdm = partial(tqdm, disable=True) for i in tqdm(iterable): -
Disable tqdm bar by environment variable after version 4.66.0:
1 2# pip install tqdm --upgrade eport TQDM_DISABLE=1Silence tqdm’s output while running tests or running the code via cron; Searched by DDG with searching “tqdm disable”
-
-
Env variable overrides supported by tqdm==4.66.0
-
leave=Falsemeans the bar will disappear instead of leaving it left after finishing. How to remove progressbar in tqdm once the iteration is complete -
Use Progress bar as status bar showing current entry, by removing all field but the description field and specifying position.
1 2 3 4 5 6 7 8outer = tqdm.tqdm(total=len(files), desc="Files", position=0) cur_file = tqdm.tqdm(total=0, position=1, bar_format="{desc}") for name in files: video = imageio.mimread(name, memtest=False) cur_file.set_description_str(f"Current file: {name}") outer.update(1)
Registration mechanism
A registry is a centralized “object” for convenience of interacting between differen components.
|
|
isinstance()
Check if an object is one of types
dataset is expected to be a list or a tuple:
|
|
Convert str to classname
-
Use eval
1eval("cls_name") -
Use getattr
1 2optim_type = 'AdamW' self.optim = getattr(torch.optim, optim_type)(optim_params, **optim_kwargs)Code from MatchNeRF.
Even and odd compatible
|
|
Code from pixelNeRF’s “nerf.py”.
Save argparse to file
(2023-09-25)
Saving python argparse file - SO
|
|
-
json has better readabiity, interoperability, security, but slower than pickle. Pickle or json?
-
json.dumpsconvert any python object to JSON formatted string, whilejson.dump()write a serialized object to file. PYnative
Write JSON File
(2024-03-21)
-
json.dump()convert a python object to a json string. GfG1 2 3 4json_data = {"camera_angle_x": fovx, "frames": frams_ls} with open(f"{dir_json}/transforms_train.json", 'w') as file: file.write(json.dumps(json_data, indent=4)) -
Write a json string into a file using
pathlibto avoid danglingwith open(): SO1 2 3json_data = {"camera_angle_x": fovx, "frames": frams_ls} pathlib.Path(f"{dir_json}/transforms_train.json").write_text(json.dumps(json_data, indent=4))- But, in this way, I don’t know how to realize
'w'that always creats a new file.
- But, in this way, I don’t know how to realize
Move a dict to GPU
(2023-09-27)
Given a dict containing list, tuple, and torch.Tensor,
-
Recursive
1 2 3 4 5 6 7 8 9 10 11 12 13 14def move_to_device(X, device): if isinstance(X, dict): for k, v in X.items(): X[k] = move_to_device(v, device) elif isinstance(X, list): for i, e in enumerate(X): X[i] = move_to_device(e, device) elif isinstance(X, tuple) and hasattr(X, "_fields"): # collections.namedtuple dd = X._asdict() dd = move_to_device(dd, device) return type(X)(**dd) elif isinstance(X, torch.Tensor): return X.to(device=device) return XCode from MatchNeRF.
Make pairs from 2 list
-
Two
forin one line:1index_lists = [(a, b) for a in range(n_views - 1) for b in range(a + 1, n_views)] # [(0,1), (0,2), (1,2)]Code from MatchNeRF.
Slice() for a dim
(2023-09-29)
|
|
Convert class to dict
(2023-10-05)
|
|
NamedTuple
(2024-04-09)
-
NamedTuple is not mutable, so the following error will occur when trying to re-assign its atttibutes: AttributeError: can’t set attribute in python - SO
1 2 3 4 5 6 7from typing import NamedTuple class BasicPointCloud(NamedTuple): points : np.array colors : np.array normals : np.array pcd.points = new_points
Format digits
-
Fix length filling with zeros: How do I format a number with a variable number of digits in Python? - SO
'123'.zfill(7): 0000123 -
f-string round a float: Fixed digits after decimal with f-strings
1 2a = 10.1234 f'{a:.2f}'
(2024-01-22)
Files
-
Open multiple files: Source code
1 2with open(scene_info.ply_path, 'rb') as src_file, open(os.path.join(self.model_path, "input.ply") , 'wb') as dest_file: dest_file.write(src_file.read())
Pass by Assignment
Python is Pass by Reference - RealPython
(2024-02-08)
-
In Python, passing arguments to a function is assigning the incoming objects to new variable name (identifier). This can be verified through “reference counter” and namespace, which is a dictionary, including key-value pairs representing a binding between target variable name and object.
1x = 2 # object 2's refcount+1, namespace add: 'x':'2' -
When an object (value) is assigned to a variable name (identifier), the reference counter of the object is incremented. If the variable name is reassigned to another value, the pre-bounded object’s reference counter is decremented.
-
Each function has its own namespace, which can be checked by
print(locals()) -
If an attribute of the object supports modification, and the object is passed to a function argument, assigning values to the object’s attribute is in-place modification. Ref
-
Misc:
-
Use
id()to get the address of a variable -
When Python modifies a variable through a function, the variable is not modified in place, but reassigned with the returned value.
-
Passing by reference in Python can be replicated with: object’s attributes, dictionary (mapping type), and list-like data (subscriptable and mutable)
-
-
Example refers to 3DGS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27class GaussianModel: def __init__(self,): self._xyz = torch.empty(0) class Scene: def __init__(self, gaussian: GaussianModel, exTen, color, ls): self.gaussian = gaussian # a binding created in locals() # The attribute _xyz supports assignment as tensor is mutable # object's attribute is modified in place: self.gaussian._xyz = torch.ones(2,3) self.myTen = exTen # exTen's refcount+1, self.myTen = torch.ones(1,4) # update to new binding self.color = color # a binding between self.color and color self.color.view(2,2) # new binding self.ls = ls self.ls[0] = 88 # affect the original list gaussian = GaussianModel() exTensor = torch.empty(0) color=torch.arange(4) myObj = Scene(gaussian, exTensor, color,ls:=[1,2]) print(gaussian._xyz) # changed to ones print(exTensor) # remain empty print(color) # unchanged print(ls) # changed to [88,2]
re
Find numbers
(2024-03-17)
How to extract numbers from a string in Python? - SO
|
|
Output: ['12.99', '5', '21321', '123213']
import
(2024-04-09)
-
Import file in 2 levels up.
ValueError: attempted relative import beyond top-level package - SO
1 2 3 4 5 6 7 8 9 10Project _3DGS scene __init__.py utils # for _3DGS # there is no __init__.py (Don't know if it matters) utils # for current project __init__.py # empty is ok file2.pyI want to use a method (
write_j) implemented infile2.pyinsidescene/__init__.py. Although, the above SO post stated that all folder and subfolders should have an__init__.py, I tried the following syntax works:1from utils.fuse_neighbors import fuse_neighborsPreviously, the 3 dots:
from ...utils.fuse_neighbors import fuse_neighbors, will lead to an error:1ValueError: attempted relative import beyond top-level package
Module
(2024-05-16)
-
A .py file is a module, not a function.
And a module cannot be called:
“combine_pcs.py”:
1 2 3def combine_plys(dataset): print(dataset) returneval.py:
1 2 3from utils import combine_pcs combine_pcs(dataset)error:
1 2 3File "/home/zi/Downloads/CasMVSNet_pl-comments/eval_refine.py", line 418, in <module> combine_pcs(dataset) TypeError: 'module' object is not callableRectify: from module import the function:
1from utils.combine_plys import combine_plys
Debug
IceCream
References:
-
使用IceCream搞定Python调试 - 微信- pythonic生物人
- Original author: 作者:Kevin Meneses González
Notes:
(2024/11/22)
- 同时输出语句和结果