88
99
1010def reads ():
11- """
12- Get hyperparameter read operations.
11+ """Get hyperparameter read operations
1312
14- Returns:
15- List[str]: hyperparameter read operations
13+ Returns
14+ -------
15+ List[str]
16+ hyperparameter read operations
1617
17- Examples:
18+ Examples
19+ --------
1820 >>> _read_tracker.clear()
1921 >>> hp = HyperParameter(a=1, b={'c': 2})
2022 >>> reads() # no read operations
@@ -36,13 +38,15 @@ def reads():
3638
3739
3840def writes ():
39- """
40- Get hyperparameter write operations.
41+ """Get hyperparameter write operations.
4142
42- Returns:
43- List[str]: hyperparameter write operations
43+ Returns
44+ -------
45+ List[str]
46+ hyperparameter write operations
4447
45- Examples:
48+ Examples
49+ --------
4650 >>> _write_tracker.clear()
4751 >>> hp = HyperParameter(a=1, b={'c': 2})
4852 >>> writes()
@@ -63,17 +67,14 @@ def writes():
6367
6468
6569def all_params ():
66- """
67- Get all tracked hyperparameters.
68- """
70+ """Get all tracked hyperparameters."""
6971 retval = list (_read_tracker .union (_write_tracker ))
7072 retval .sort ()
7173 return retval
7274
7375
7476class _Accessor (dict ):
75- """
76- Helper for accessing hyper-parameters.
77+ """Helper for accessing hyper-parameters.
7778
7879 When reading an undefined parameter, the accessor will:
7980 1. return false in `if` statement:
@@ -99,9 +100,7 @@ def __init__(self, root, path=None):
99100 self ._path = path
100101
101102 def get_or_else (self , default : Any = None ):
102- """
103- Get value for the parameter, or get default value if the parameter is not defined.
104- """
103+ """Get value for the parameter, or get default value if the parameter is not defined."""
105104 _read_tracker .add (self ._path )
106105 value = self ._root .get (self ._path )
107106 return default if not value else value
@@ -141,10 +140,10 @@ def __call__(self, default: Any = None) -> Any:
141140
142141
143142class DynamicDispatch :
144- """
145- Dynamic call dispatch
143+ """Dynamic call dispatcher
146144
147- Examples:
145+ Examples
146+ --------
148147
149148 >>> @dynamic_dispatch
150149 ... def debug_print(*args, **kws):
@@ -204,6 +203,9 @@ def dynamic_dispatch(func, name=None, index=None):
204203class HyperParameter (dict ):
205204 """HyperParameter is an extended dict with features for better parameter management.
206205
206+ **create and access hyper-parameters**
207+ ======================================
208+
207209 Examples
208210 --------
209211 >>> hp = HyperParameter(param1=1, param2=2, obj1={'propA': 'A'})
@@ -222,6 +224,21 @@ class HyperParameter(dict):
222224
223225 The object-style api also support creating or updating the parameters:
224226 >>> hp.a.b.c = 1
227+
228+ **undefined parameters and default values**
229+ ===========================================
230+
231+ Examples
232+ --------
233+ 1. undefined parameter in `if` statement:
234+ >>> params = HyperParameter()
235+ >>> if not params.undefined_int: print("parameter undefined")
236+ parameter undefined
237+
238+ 2. default value for undefined parameter
239+ >>> params = HyperParameter()
240+ >>> params.undefined_int(10)
241+ 10
225242 """
226243
227244 def __init__ (self , ** kws ):
@@ -379,13 +396,13 @@ def __call__(self) -> Any:
379396 Examples
380397 --------
381398 >>> cfg = HyperParameter(a=1, b = {'c':2, 'd': 3})
382- >>> cfg().a.get_or_else ('default') # default value for simple parameter
399+ >>> cfg().a('default') # default value for simple parameter
383400 1
384401
385- >>> cfg().b.c.get_or_else ('default') # default value for nested parameter
402+ >>> cfg().b.c('default') # default value for nested parameter
386403 2
387404
388- >>> cfg().b.undefined.get_or_else ('default')
405+ >>> cfg().b.undefined('default')
389406 'default'
390407 """
391408
@@ -411,10 +428,10 @@ def load(f):
411428
412429
413430class param_scope (HyperParameter ):
414- """
415- thread-safe scoped hyperparameter
431+ """A thread-safe context scope that manages hyperparameters
416432
417- Examples:
433+ Examples
434+ --------
418435 create a scoped HyperParameter
419436 >>> with param_scope(**{'a': 1, 'b': 2}) as cfg:
420437 ... print(cfg.a)
@@ -459,13 +476,20 @@ def __exit__(self, exc_type, exc_value, traceback):
459476 param_scope .tls .history .pop ()
460477
461478 @staticmethod
462- def init (params ):
479+ def current ():
480+ if not hasattr (param_scope .tls , "history" ):
481+ param_scope .init ()
482+ return param_scope .tls .history [- 1 ]
483+
484+ @staticmethod
485+ def init (params = None ):
463486 """
464487 init param_scope for a new thread.
465488 """
466- if not hasattr (param_scope .tls , "history" ):
467- param_scope .tls .history = []
468- param_scope .tls .history .append (params )
489+ param_scope .tls .history = []
490+ param_scope .tls .history .append (
491+ params if params is not None else HyperParameter ()
492+ )
469493
470494
471495"""
@@ -484,7 +508,8 @@ def auto_param(name_or_func):
484508 """
485509 Convert keyword arguments into hyperparameters
486510
487- Examples:
511+ Examples
512+ --------
488513
489514 >>> @auto_param
490515 ... def foo(a, b=2, c='c', d=None):
0 commit comments