Yes:ifminimum<1024:# Note that this raising of ValueError is not mentioned in the doc# string's "Raises:" section because it is not appropriate to# guarantee this specific behavioral reaction to API misuse.raiseValueError(f'Min. port must be at least 1024, not {minimum}.')port=self._find_next_open_port(minimum)ifportisNone:raiseConnectionError(f'Could not connect to service on port {minimum} or higher.')
Python
1234567
No:assertminimum>=1024,'Minimum port must be at least 1024.'# The following code depends on the previous assert.port=self._find_next_open_port(minimum)assertportisnotNone# The type checking of the return statement relies on the assert.
Yes:# layer 1: just for first iterationresult=[mapping_exprforvalueiniterableiffilter_expr]# layer 2: just for second-level filterresult=[is_valid(metric={'key':value})forvalueininteresting_iterableifa_longer_filter_expression(value)]# same idea heredescriptive_name=[transform({'key':key,'value':value},color='black')forkey,valueingenerate_iterable(some_input)ifcomplicated_condition_is_met(key,value)]result=[]forxinrange(10):foryinrange(5):ifx*y>10:result.append((x,y))return{x:complicated_transform(x)forxinlong_generator_function(parameter)ifxisnotNone}return(x**2forxinrange(10))unique_names={user.nameforuserinusersifuserisnotNone}
defsimple_decorator(func):# arg(func) here refers to say_hello()# define the action of decorator functiondefwrapper():print("Before calling the function.")func()# func here refers to say_hello() instanceprint("After calling the function.")# let it go!returnwrapper@simple_decoratordefsay_hello():print("Hello!")say_hello()
defdecorator_with_args(func):defwrapper(*args,**kwargs):# all original args should be listed here!print("Before calling the function.")result=func(*args,**kwargs)# original function callingprint("After calling the function.")returnresultreturnwrapper@decorator_with_argsdefadd(a,b):returna+bresult=add(2,3)print(f"Result: {result}")
defmultiply_decorator(func):defwrapper(*args,**kwargs):result=func(*args,**kwargs)# original function callingreturnresult*2# modify return valuereturnwrapper@multiply_decoratordefadd(a,b):returna+bresult=add(2,3)print(f"Result after decoration: {result}")
def_retry_zones(self,to_provision:resources_lib.Resources,num_nodes:int,requested_resources:Set[resources_lib.Resources],dryrun:bool,stream_logs:bool,cluster_name:str,cloud_user_identity:Optional[List[str]],prev_cluster_status:Optional[status_lib.ClusterStatus],prev_handle:Optional['CloudVmRayResourceHandle'],prev_cluster_ever_up:bool,skip_if_config_hash_matches:Optional[str],)->Dict[str,Any]:"""The provision retry loop. Returns a config_dict with the following fields: All fields from backend_utils.write_cluster_config(). See its docstring. - 'provisioning_skipped': True if provisioning was short-circuited by skip_if_config_hash_matches, False otherwise. - 'handle': The provisioned cluster handle. - 'provision_record': (Only if using the new skypilot provisioner) The record returned by provisioner.bulk_provision(). - 'resources_vars': (Only if using the new skypilot provisioner) The resources variables given by make_deploy_resources_variables(). """# Get log_path namelog_path=os.path.join(self.log_dir,'provision.log')log_abs_path=os.path.abspath(log_path)ifnotdryrun:os.makedirs(os.path.expanduser(self.log_dir),exist_ok=True)os.system(f'touch {log_path}')rich_utils.force_update_status(ux_utils.spinner_message('Launching',log_path))# Get previous cluster statuscluster_exists=prev_cluster_statusisnotNoneassertto_provision.regionisnotNone,(to_provision,'region should have been set by the optimizer.')region=clouds.Region(to_provision.region)# Optimization - check if user has non-zero quota for# the instance type in the target region. If not, fail early# instead of trying to provision and failing later.try:need_provision=to_provision.cloud.check_quota_available(to_provision)exceptExceptionase:# pylint: disable=broad-exceptneed_provision=Truelogger.info(f'Error occurred when trying to check quota. 'f'Proceeding assuming quotas are available. Error: 'f'{common_utils.format_exception(e,use_bracket=True)}')
def_retry_zones(self,to_provision:resources_lib.Resources,num_nodes:int,requested_resources:Set[resources_lib.Resources],dryrun:bool,stream_logs:bool,cluster_name:str,cloud_user_identity:Optional[List[str]],prev_cluster_status:Optional[status_lib.ClusterStatus],prev_handle:Optional['CloudVmRayResourceHandle'],prev_cluster_ever_up:bool,skip_if_config_hash_matches:Optional[str],)->Dict[str,Any]:"""The provision retry loop. Returns a config_dict with the following fields: All fields from backend_utils.write_cluster_config(). See its docstring. - 'provisioning_skipped': True if provisioning was short-circuited by skip_if_config_hash_matches, False otherwise. - 'handle': The provisioned cluster handle. - 'provision_record': (Only if using the new skypilot provisioner) The record returned by provisioner.bulk_provision(). - 'resources_vars': (Only if using the new skypilot provisioner) The resources variables given by make_deploy_resources_variables(). """
这里的明确范式是:
Python
1 2 3 4 5 6 7 8 91011
"""A one-line summary of the module or program, terminated by a period.Leave one blank line. The rest of this docstring should contain anoverall description of the module or program. Optionally, it may alsocontain a brief description of exported classes and functions and/or usageexamples.Typical usage - return value / type and their meanings: foo = ClassFoo() bar = foo.FunctionBar()"""
```bash
python -m pydoc os
```
或者查看模块的 Web 文档:
```bash
python -m pydoc -p 8081
```
这样会在本地启动一个 Web 服务器,访问 `http://localhost:8081` 查看文档。
对于函数中间的解释,更多的是行文上的逻辑解释,这里就不要按docstrings来了:
Python
1 2 3 4 5 6 7 8 9101112
# Optimization - check if user has non-zero quota for# the instance type in the target region. If not, fail early# instead of trying to provision and failing later.try:need_provision=to_provision.cloud.check_quota_available(to_provision)exceptExceptionase:# pylint: disable=broad-exceptneed_provision=Truelogger.info(f'Error occurred when trying to check quota. 'f'Proceeding assuming quotas are available. Error: 'f'{common_utils.format_exception(e,use_bracket=True)}')
deffetch_smalltable_rows(table_handle:smalltable.Table,keys:Sequence[bytes|str],require_all_keys:bool=False,)->Mapping[bytes,tuple[str,...]]:"""Description for this function in one line. Detailed description for this function. as a graph. ... ... Args: table_handle: An open smalltable.Table instance. keys: A sequence of strings representing the key of each table row to fetch. String keys will be UTF-8 encoded. require_all_keys: If True only rows with values set for all keys will be returned. Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. For example: {b'Serak': ('Rigel VII', 'Preparer'), b'Zim': ('Irk', 'Invader'), b'Lrrr': ('Omicron Persei 8', 'Emperor')} Returned keys are always bytes. If a key from the keys argument is missing from the dictionary, then that row was not found in the table (and require_all_keys must have been False). Raises: IOError: An error occurred accessing the smalltable. """
classSampleClass:"""Summary of class here. Longer class information... Longer class information... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """def__init__(self,likes_spam:bool=False):"""Initializes the instance based on spam preference. Args: likes_spam: Defines if instance exhibits this preference. """self.likes_spam=likes_spamself.eggs=0@propertydefbutter_sticks(self)->int:"""The number of butter sticks we have."""
long_string="""This is fine if your use case can accept extraneous leading spaces."""long_string=("And this too is fine if you cannot accept\n""extraneous leading spaces.")long_string=("And this is fine if you cannot accept\n"+"extraneous leading spaces.")
正如上面所示,连接两个引号子句可以直接换行,也可以在第一个句末给一个+ 😊
logging msg 不可以用 f-string
Python
123
importtensorflowastflogger=tf.get_logger()logger.info('TensorFlow Version is: %s',tf.__version__)
原因是:
log的语法格式是log(log_msg,reason),只有 a string literal 才能与之匹配
Error Messages
写错误处理一定要注意,不仅要报“这是什么类型的错误”,还要报“导致这个错误的原因”
Python
12345678
ifnot0<=p<=1:raiseValueError(f'Not a probability: {p=}')try:os.rmdir(workdir)exceptOSErroraserror:logging.warning('Could not remove directory (reason: %r): %r',error,workdir)
# standard libraryimportcollectionsimportqueueimportsys# 3rd partyfromabslimportappfromabslimportflagsimportbs4importcryptographyimporttensorflowastf# file system itselffrombook.genresimportscififrommyproject.backendimporthuxleyfrommyproject.backend.hgwellsimporttime_machinefrommyproject.backend.state_machineimportmain_loopfromotherproject.aiimportbodyfromotherproject.aiimportmindfromotherproject.aiimportsoul