精华内容
下载资源
问答
  • Dockerfile FROM指令 语法解析

    千次阅读 2020-11-05 09:43:35
      凡是编写Dockerfile,几乎开始都会是FROM命令,它决定了Dockerfile构建出的镜像为何物,本文就来了解一下FROM的语法、语义以及对应的示例。   语法 FROM [--platform=<platform>] <image> [AS <...

      凡是编写Dockerfile,几乎开始都会是FROM命令,它决定了Dockerfile构建出的镜像为何物,本文就来了解一下FROM的语法、语义以及对应的示例。

      语法

    FROM [--platform=<platform>] <image> [AS <name>]
    FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
    FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
    

      语义

      1. FROM指令开始一个新的构建阶段,设置后续构建依赖的基础镜像,Dockerfile必须以FROM开始。镜像可以是任意有效镜像。

      示例:在nginx:latest镜像基础上,直接创建一个新的镜像。

    FROM nginx
    CMD /bin/bash
    

    在这里插入图片描述

      2. Dockerfile必须以FROM指令开始(除ARG指令之外),否则会出现"Please provide a source image with from prior to commit"。

    CMD echo "Before FROM"
    FROM nginx
    CMD /bin/bash
    

    在这里插入图片描述

      3. FROM可以在一个Dockerfile中出现多次,以创建多个镜像或者将当前构建作为另一个构建的依赖。

      4. 通过向FROM指令添加AS name,可以选择为新生成阶段指定名称。该名称可以在后续的FROMCOPY --FROM=<name>指令中使用,以引用在此阶段中构建的镜像。

      示例:详细应用示例会在系列博文中展示。

    FROM nginx AS firstNginx
    CMD /bin/bash
    

      5. tag或者digest的值是可选的。如果省略其中任何一个,则默认情况下,构建器使用latest作为默认值。如果找不到tag的值,则构建器返回错误。

      示例:直接不存在的镜像nginx:109,下载出现错误。

    FROM nginx:109
    CMD /bin/bash
    

    在这里插入图片描述

      6. --platform可以用于指定镜像的平台,用来处理那些支持多平台的镜像。例如:linux/amd64linux/arm64windows/amd64。默认情况下,使用生产请求的平台。全局生成参数可用于此标志的值,例如:自动平台参数允许您强制一个阶段到本机构建平台(--platform=$BUILDPLATFORM),并使用它交叉编译到阶段内部的目标平台。

      示例:nginx:latest作为基础镜像,指定--platform=linux/arm64进行镜像构建。

    FROM --platform=linux/arm64 nginx
    CMD /bin/bash
    

    在这里插入图片描述

    在这里插入图片描述

      7. FROMARG

      上文(2)中曾提到过, Dockerfile必须以FROM指令开始(除ARG指令之外),下面来看下FROMARG的关系。

      7.1 FORM的参数支持在FORM之前由ARG定义的变量。

      示例:在FROM之前通过ARG定义变量NG_VERSION,在FROM中引用变量。

    ARG NG_VERSION=1.19.3
    FROM nginx:${NG_VERSION}
    CMD /bin/bash
    

    在这里插入图片描述

    在这里插入图片描述

      7.2 FORM之前声明的ARG参数游离在构建阶段之外,所以不可以在FORM之后的任何指令中使用。如果想使用FORM前声明的带有默认值的ARG,需要在构建阶段通过ARG声明没有值的同名参数。

    ARG NG_VERSION=1.19.3
    FROM nginx:${NG_VERSION}
    ARG NG_VERSION
    RUN echo "${NG_VERSION}"
    CMD /bin/bash
    

    在这里插入图片描述

      总结

      FROM指令应用非常简单,但一定要注意文中罗列的7项内容,避免在实际应用中,由于失误等原因造成不必要的麻烦,本文演示的示例都很简单,都是基于镜像直接创建新的镜像,但如何使用Dockerfile构建镜像基本也就是这样了。

      若文中存在错误和不足,欢迎指正!

    展开全文
  • sklearn:sklearn.feature_selection的SelectFromModel函数的简介、使用方法之详细攻略 目录 SelectFromModel函数的简介 1、使用SelectFromModel和LassoCV进行特征选择 2、L1-based feature selection 3、...

    sklearn:sklearn.feature_selection的SelectFromModel函数的简介、使用方法之详细攻略

     

     

    目录

    SelectFromModel函数的简介

    1、使用SelectFromModel和LassoCV进行特征选择

    2、L1-based feature selection

    3、Tree-based feature selection

    SelectFromModel函数的使用方法

    1、SelectFromModel的原生代码


     

     

    SelectFromModel函数的简介

            SelectFromModel is a meta-transformer that can be used along with any estimator that has a coef_ or feature_importances_ attribute after fitting. The features are considered unimportant and removed, if the corresponding coef_ or feature_importances_ values are below the provided threshold parameter. Apart from specifying the threshold numerically, there are built-in heuristics for finding a threshold using a string argument. Available heuristics are “mean”, “median” and float multiples of these like “0.1*mean”.
            SelectFromModel是一个元转换器,可以与任何在拟合后具有coef_或feature_importances_属性的estimator 一起使用。如果相应的coef_或feature_importances_值低于提供的阈值参数,则认为这些特性不重要并将其删除。除了以数字方式指定阈值外,还有使用字符串参数查找阈值的内置启发式方法。可用的试探法是“平均数”、“中位数”和这些数的浮点倍数,如“0.1*平均数”。

     

     

    官网APIhttps://scikit-learn.org/stable/modules/feature_selection.html#feature-selection-using-selectfrommodel

      """Meta-transformer for selecting features based on importance weights.    .. versionadded:: 0.17

    用于根据重要性权重来选择特征的元转换器

    . .加入在0.17版本::

          Parameters
        ----------
        estimator : object
        The base estimator from which the transformer is built.
        This can be both a fitted (if ``prefit`` is set to True)
        or a non-fitted estimator. The estimator must have either a
        ``feature_importances_`` or ``coef_`` attribute after fitting.
        
        threshold : string, float, optional default None
        The threshold value to use for feature selection. Features whose
        importance is greater or equal are kept while the others are
        discarded. If "median" (resp. "mean"), then the ``threshold`` value is
        the median (resp. the mean) of the feature importances. A scaling
        factor (e.g., "1.25*mean") may also be used. If None and if the
        estimator has a parameter penalty set to l1, either explicitly
        or implicitly (e.g, Lasso), the threshold used is 1e-5.
        Otherwise, "mean" is used by default.
        
        prefit : bool, default False
        Whether a prefit model is expected to be passed into the constructor
        directly or not. If True, ``transform`` must be called directly
        and SelectFromModel cannot be used with ``cross_val_score``,
        ``GridSearchCV`` and similar utilities that clone the estimator.
        Otherwise train the model using ``fit`` and then ``transform`` to do
        feature selection.
        
        norm_order : non-zero int, inf, -inf, default 1
        Order of the norm used to filter the vectors of coefficients below
        ``threshold`` in the case where the ``coef_`` attribute of the
        estimator is of dimension 2.

    参数
    estimator :对象类型,
    建立转换的基本estimator 。
    这可以是一个拟合(如果' ' prefit ' '被设置为True) 或者非拟合的estimator。在拟合之后,estimator 必须有' ' feature_importances_ ' '或' ' coef_ ' '属性。


    threshold :字符串,浮点类型,可选的,默认无

    用于特征选择的阈值。重要性大于或等于的特征被保留,其他特征被丢弃。如果“中位数”(分别地。(“均值”),则“阈值”为中位数(resp,特征重要性的平均值)。也可以使用比例因子(例如“1.25*平均值”)。如果没有,并且估计量有一个参数惩罚设置为l1,不管是显式的还是隐式的(例如Lasso),阈值为1e-5。否则,默认使用“mean”。


    prefit: bool,默认为False

    prefit模型是否应直接传递给构造函数。如果为True,则必须直接调用“transform”,SelectFromModel不能与cross_val_score 、GridSearchCV以及类似的克隆估计器的实用程序一起使用。否则,使用' ' fit ' '和' ' transform ' '训练模型进行特征选择。


    norm_order:非零整型,inf, -inf,默认值1
    在estimator的' coef_ 属性为2维的情况下,用于过滤' '阈值' '以下系数的向量的范数的顺序。

        Attributes
        ----------
        estimator_ : an estimator
        The base estimator from which the transformer is built.
        This is stored only when a non-fitted estimator is passed to the
        ``SelectFromModel``, i.e when prefit is False.
        
        threshold_ : float
        The threshold value used for feature selection.
        """

    属性
    estimator_:一个estimator。

    建立转换器的基estimator,只有在将非拟合估计量传递给SelectFromModel 时,才会存储它。当prefit 为假时。

     

    threshold_ :浮点类型
    用于特征选择的阈值。

     

    1、使用SelectFromModel和LassoCV进行特征选择

    # Author: Manoj Kumar <mks542@nyu.edu>
    # License: BSD 3 clause
    
    print(__doc__)
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    from sklearn.datasets import load_boston
    from sklearn.feature_selection import SelectFromModel
    from sklearn.linear_model import LassoCV
    
    # Load the boston dataset.
    X, y = load_boston(return_X_y=True)
    
    # We use the base estimator LassoCV since the L1 norm promotes sparsity of features.
    clf = LassoCV()
    
    # Set a minimum threshold of 0.25
    sfm = SelectFromModel(clf, threshold=0.25)
    sfm.fit(X, y)
    n_features = sfm.transform(X).shape[1]
    
    # Reset the threshold till the number of features equals two.
    # Note that the attribute can be set directly instead of repeatedly
    # fitting the metatransformer.
    while n_features > 2:
        sfm.threshold += 0.1
        X_transform = sfm.transform(X)
        n_features = X_transform.shape[1]
    
    # Plot the selected two features from X.
    plt.title(
        "Features selected from Boston using SelectFromModel with "
        "threshold %0.3f." % sfm.threshold)
    feature1 = X_transform[:, 0]
    feature2 = X_transform[:, 1]
    plt.plot(feature1, feature2, 'r.')
    plt.xlabel("Feature number 1")
    plt.ylabel("Feature number 2")
    plt.ylim([np.min(feature2), np.max(feature2)])
    plt.show()

    2、L1-based feature selection

    >>> from sklearn.svm import LinearSVC
    >>> from sklearn.datasets import load_iris
    >>> from sklearn.feature_selection import SelectFromModel
    >>> X, y = load_iris(return_X_y=True)
    >>> X.shape
    (150, 4)
    >>> lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
    >>> model = SelectFromModel(lsvc, prefit=True)
    >>> X_new = model.transform(X)
    >>> X_new.shape
    (150, 3)

     

    3、Tree-based feature selection

    >>> from sklearn.ensemble import ExtraTreesClassifier
    >>> from sklearn.datasets import load_iris
    >>> from sklearn.feature_selection import SelectFromModel
    >>> X, y = load_iris(return_X_y=True)
    >>> X.shape
    (150, 4)
    >>> clf = ExtraTreesClassifier(n_estimators=50)
    >>> clf = clf.fit(X, y)
    >>> clf.feature_importances_  
    array([ 0.04...,  0.05...,  0.4...,  0.4...])
    >>> model = SelectFromModel(clf, prefit=True)
    >>> X_new = model.transform(X)
    >>> X_new.shape               
    (150, 2)

     

     

    SelectFromModel函数的使用方法

    1、SelectFromModel的原生代码

    class SelectFromModel Found at: sklearn.feature_selection.from_model
    
    class SelectFromModel(BaseEstimator, SelectorMixin, MetaEstimatorMixin):
        """Meta-transformer for selecting features based on importance weights.
        
        .. versionadded:: 0.17
        
        Parameters
        ----------
        estimator : object
        The base estimator from which the transformer is built.
        This can be both a fitted (if ``prefit`` is set to True)
        or a non-fitted estimator. The estimator must have either a
        ``feature_importances_`` or ``coef_`` attribute after fitting.
        
        threshold : string, float, optional default None
        The threshold value to use for feature selection. Features whose
        importance is greater or equal are kept while the others are
        discarded. If "median" (resp. "mean"), then the ``threshold`` value is
        the median (resp. the mean) of the feature importances. A scaling
        factor (e.g., "1.25*mean") may also be used. If None and if the
        estimator has a parameter penalty set to l1, either explicitly
        or implicitly (e.g, Lasso), the threshold used is 1e-5.
        Otherwise, "mean" is used by default.
        
        prefit : bool, default False
        Whether a prefit model is expected to be passed into the constructor
        directly or not. If True, ``transform`` must be called directly
        and SelectFromModel cannot be used with ``cross_val_score``,
        ``GridSearchCV`` and similar utilities that clone the estimator.
        Otherwise train the model using ``fit`` and then ``transform`` to do
        feature selection.
        
        norm_order : non-zero int, inf, -inf, default 1
        Order of the norm used to filter the vectors of coefficients below
        ``threshold`` in the case where the ``coef_`` attribute of the
        estimator is of dimension 2.
        
        Attributes
        ----------
        estimator_ : an estimator
        The base estimator from which the transformer is built.
        This is stored only when a non-fitted estimator is passed to the
        ``SelectFromModel``, i.e when prefit is False.
        
        threshold_ : float
        The threshold value used for feature selection.
        """
        def __init__(self, estimator, threshold=None, prefit=False, 
         norm_order=1):
            self.estimator = estimator
            self.threshold = threshold
            self.prefit = prefit
            self.norm_order = norm_order
        
        def _get_support_mask(self):
        # SelectFromModel can directly call on transform.
            if self.prefit:
                estimator = self.estimator
            elif hasattr(self, 'estimator_'):
                estimator = self.estimator_
            else:
                raise ValueError(
                    'Either fit SelectFromModel before transform or set "prefit='
                    'True" and pass a fitted estimator to the constructor.')
            scores = _get_feature_importances(estimator, self.norm_order)
            threshold = _calculate_threshold(estimator, scores, self.threshold)
            return scores >= threshold
        
        def fit(self, X, y=None, **fit_params):
            """Fit the SelectFromModel meta-transformer.
    
            Parameters
            ----------
            X : array-like of shape (n_samples, n_features)
                The training input samples.
    
            y : array-like, shape (n_samples,)
                The target values (integers that correspond to classes in
                classification, real numbers in regression).
    
            **fit_params : Other estimator specific parameters
    
            Returns
            -------
            self : object
                Returns self.
            """
            if self.prefit:
                raise NotFittedError(
                    "Since 'prefit=True', call transform directly")
            self.estimator_ = clone(self.estimator)
            self.estimator_.fit(X, y, **fit_params)
            return self
        
        @property
        def threshold_(self):
            scores = _get_feature_importances(self.estimator_, self.norm_order)
            return _calculate_threshold(self.estimator, scores, self.threshold)
        
        @if_delegate_has_method('estimator')
        def partial_fit(self, X, y=None, **fit_params):
            """Fit the SelectFromModel meta-transformer only once.
    
            Parameters
            ----------
            X : array-like of shape (n_samples, n_features)
                The training input samples.
    
            y : array-like, shape (n_samples,)
                The target values (integers that correspond to classes in
                classification, real numbers in regression).
    
            **fit_params : Other estimator specific parameters
    
            Returns
            -------
            self : object
                Returns self.
            """
            if self.prefit:
                raise NotFittedError(
                    "Since 'prefit=True', call transform directly")
            if not hasattr(self, "estimator_"):
                self.estimator_ = clone(self.estimator)
            self.estimator_.partial_fit(X, y, **fit_params)
            return self

     

     

     

     

    展开全文
  • Python的from和import用法

    万次阅读 多人点赞 2019-06-22 11:01:38
    不过,使用from时,只要你了解并预料到可能发生这种事,在实际情况下这就不是一个大问题了,尤其是当你明确列出导入变量名时(例如,from module import x, y, z)。 另一方面,from module import *形式的确可能...

         import使一个变量名引用整个模块对象,因此必须通过模块名称来得到该模块的属性,比如我们导入一个数学计算的模块 math:

     import math
     print math.pi #导出圆周率的值
    
    >>>3.14159265359

        我们导入math模块,在python模块学习中我们会知道,这样做会得到名math的对象,这个模块对象包含了pi这样的常量,以及一些其它的方法。我们如果直接访问 pi,不加math这个前缀会发生什么情况呢?

    print pi
    
    Traceback (most recent call last):
      File "<pyshell#6>", line 1, in <module>
        print pi
    NameError: name 'pi' is not defined

          程序抛出了一个名为“NameError”的错误。这个时候我们可以用from这个方法来实现可以直接用pi这个方法。from会把变量名复制到另一个作用域,所以它就可以直接在脚本中使用复制后的变量名,而不用通过模块,例如:

    from math import pi
    print pi
    >>>3.141592653589793

    这样我们就可以直接输出 pi的值了,而不会报错,不需要加那个模块名加句号。有的朋友可能感觉还是比较麻烦,有会有更快速、更省事的Python模块导入方法呢?还真有。

    from math import *
    pi
    cos(pi)
    >>>3.141592653589793
    >>> -1.0

         这样就不需要一个一样导入模块内部的方法了,一次性的将所有python 调用函数方法导入,好处是代码看起来非常简洁,但是如果同时导入多个模块,要考虑模块方法名冲突等这些问题,至于怎么样使用,要看你的使用环境 。

    from :https://www.iplaypy.com/jinjie/from-import.html

     

    • from语句有破坏命名空间的潜质。如果使用from导入变量,变量碰巧和作用域中现有变量重名,变量就会被悄悄的覆盖掉。
    • 使用import语句时就不存在这种问题,因为必须通过模块名才能获取其内容。不过,使用from时,只要你了解并预料到可能发生这种事,在实际情况下这就不是一个大问题了,尤其是当你明确列出导入变量名时(例如,from module import x, y, z)。
    • 另一方面,from module import *形式的确可能破坏命名空间,让变量名难以理解,尤其是在导入一个以上的文件时。

      比较务实的建议是:简单的模块一般倾向于使用import,而不是from。多数的from语句是用于明确列举想要的变量,而且限制在每个文件中只用一次from *形式。这样一来,任何无定义的变量名都可以认为是存在于from *所引用的模块内。当你必须使用两个不同模块内定义的相同变量名变量时,才真的必须使用import,这种情况下不能使用from。

     

    二、Python中的模块和包

        每个.py文件都是可以认为是一个Python模块,.py文件中可以包含类、方法、变量和常量(Python还没有严格意义上的常量,只是约定大写的变量作为常量),文件内也可以直接写所有的逻辑语句并在加载时从上之下直接执行,这与其他解释型语言是类似的。例如我们选择在文件夹ModuleAndPackage中创建一个文本文件person.py文件即创建了一个简单的Python模块,

          Python需要去某些固定的路径下去查找Python模块,上面我们设置在ModuleAndPackage中查找。但是这些路径下也是有目录层次的,Python是如何查找子目录中的模块呢?特别是引用第三方包时,我们也需要知道一定的层次关系。实际上,Python通过目录和文件构建包结构,并且包是层层嵌套的,这样就构成了包内的访问路径。例如我们在ModuleAndPackage文件夹下,创建一个文件夹animal,里面创建一个文本文件pet.py。

         那么如何引用pet.py这个模块呢?按照Python的约定,需要在animal文件夹中创建名为__init__.py的空文本文件,以标识animal文件夹是一个包。倘若animal文件夹内还有文件夹作为包,也必须包含__init__.py文件。这样就层层标识了访问的路径。

       简答来说,只要Python模块在其执行环境配置的搜索路径中,并且其所在位置是包结构的一部分,那么我们就可以引用该模块。

    from:https://www.cnblogs.com/qingspace/archive/2016/03/16/5284480.html

    Python中在脚本中引用其他文件函数的方法

         在导入文件的时候,Python只搜索当前脚本所在的目录,加载(entry-point)入口脚本运行目录和sys.path中包含的路径例如包的安装地址。所以如果要在当前脚本引用其他文件,除了将文件放在和脚本同一目录下,还有以下几种方法。

    1. 将文件所在位置添加到sys.path中

    通过sys模块的append方法在Python环境中增加搜索路径。

    import sys
    sys.path.insert(0, '/path/to/application/app/folder')
    sys.path.append('/path/to/application/app/folder')#2个都行
    
    import file

    ./ 当前目录。    ../ 父级目录。     / 根目录。 

    2. 在文件目录下新建__init__.py文件然后调用文件

    from application.app.folder.file import func_name

    __init__.py文件的作用

            该文件的主要作用使初始化Python包。如果目录下面包含了该文件,Python解释器就会将该目录当做一个包,下一步就可以使用import语句在别的.py脚本中引用该目录下的文件。一个标准Python模块的结构如下所示:

    package/
        __init__.py
        file.py
        file2.py
        subpackage/
            __init__.py
            submodule1.py
            submodule2.py

           __init__文件可以为空但可以用来建立对包的需求。一般来说会在该文件中写那些类,函数等需要被导入到包水平,从而可以被方便的引用。__init__文件提前准备包内需要被引用的各个模块中的变量,类似于向外部引用者暴露包内接口

    1、如果file.py文件中有一个File类,在__init__.py文件中啥都没写时引用File类需要这样操作:

    from package.file import File

    2、如果在__init__.py文件中将file导入包,那就在包水平可以直接引用File类:

    # in your __init__.py
    from file import File
    
    # in your script
    from package import File

         此外,还需要注意的一点是:如果解释器在__init__.py文件中观察到了__all__变量,那么在运行from package import *时就只会引入__all__变量中列出的那些模块。例如:如果想在上述结构的只引入submodule1模块,那么可以在subpackage/__init__.py文件中定义__all__ = ['submodule1'],当引用subpackage时from subpackage import *就只引入了submodule1模块。

     from:https://www.cnblogs.com/arkenstone/p/5609063.html

    展开全文
  • python协程系列(三)——yield from原理详解

    千次阅读 多人点赞 2018-12-26 14:45:28
    声明:本文将详细讲解python协程的实现机理,为了彻底的弄明白它到底是怎么一回...本次系列文章“python协程系列文章”将从最简单的生成器、yield、yield from说起,然后详细讲解asyncio的实现方式。本文主要讲解什...

    声明:本文将详细讲解python协程的实现机理,为了彻底的弄明白它到底是怎么一回事,鉴于篇幅较长,将彻底从最简单的yield说起从最简单的生成器开始说起,因为很多看到这样一句话的时候很懵,即“yield也是一种简单的协程”,这到底是为什么呢?本次系列文章“python协程系列文章”将从最简单的生成器、yield、yield from说起,然后详细讲解asyncio的实现方式。本文主要讲解什么是yield from的详细实现、它有什么作用、实现动机是什么,将一层一层揭开它的面纱。

    一、yield from 的简单实现

    从前面的系列文章中,我们了解到,yield是每次“惰性返回”一个值,其实从名字中就能看出,yield from 是yield的升级改进版本,如果将yield理解成“返回”,那么yield from就是“从什么(生成器)里面返回”,这就构成了yield from的一般语法,即

    yield from generator

    这样的形式。我们通过一个简单例子来看:

    def generator2():
        yield 'a'
        yield 'b'
        yield 'c'
        yield from generator1() #yield from iterable本质上等于 for item in iterable: yield item的缩写版
        yield from [11,22,33,44]
        yield from (12,23,34)
        yield from range(3)
    
    
    for i in generator2():
        print(i,end=' , ')
    '''运行的结果为:
    a , b , c , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11 , 22 , 33 , 44 , 12 , 23 , 34 , 0 , 1 , 2 ,
    '''

    总结:
    从上面的代码可以看书,yield from 后面可以跟的可以是“ 生成器 、元组、 列表、range()函数产生的序列等可迭代对象

    简单地说,yield from  generator 。实际上就是返回另外一个生成器。而yield只是返回一个元素。从这个层面来说,有下面的等价关系:yield from iterable本质上等于 for item in iterable: yield item 。

    二、yield from的高级应用

    当然,yield from既然称之为yield的升级改进版,如果仅仅是上面的那一点作用,显然这是不够的,因为那仅仅简化了一两句代码的事情。系列文章的上一篇讲解了yield所存在的缺点,参见上一篇文章:

    https://blog.csdn.net/qq_27825451/article/details/85234610

    yield from正式针对哪些不足来加以改进的。

    1、针对yield无法获取生成器return的返回值

    我们都知道,在使用yield生成器的时候,如果使用for语句去迭代生成器,则不会显式的出发StopIteration异常,而是自动捕获StopIteration异常,所以如果遇到return,只是会终止迭代,而不会触发异常,故而也就没办法获取return的值。如下:

    def my_generator():
        for i in range(5):
            if i==2:
                return '我被迫中断了'
            else:
                yield i
    
    def main(generator):
        try:
            for i in generator:  #不会显式触发异常,故而无法获取到return的值
                print(i)
        except StopIteration as exc:
            print(exc.value)
    
    g=my_generator()  #调用
    main(g)
    '''运行结果为:
    0
    1
    '''

    从上面的例子可以看出,for迭代语句不会显式触发异常,故而无法获取到return的值,迭代到2的时候遇到return语句,隐式的触发了StopIteration异常,就终止迭代了,但是在程序中不会显示出来。

    但是如果我是使用next(g)一次一次迭代,则会显式触发异常,但要获取return的返回值,我需要如下操作:

    def my_generator():
        for i in range(5):
            if i==2:
                return '我被迫中断了'
            else:
                yield i
    
    def main(generator):
        try:
            print(next(generator))   #每次迭代一个值,则会显式出发StopIteration
            print(next(generator))
            print(next(generator))
            print(next(generator))
            print(next(generator))
        except StopIteration as exc:
            print(exc.value)     #获取返回的值
    
    g=my_generator()
    main(g)
    '''运行结果为:
    0
    1
    我被迫中断了
    '''

    现在我们使用yield from来完成上面的同样的功能:

    def my_generator():
        for i in range(5):
            if i==2:
                return '我被迫中断了'
            else:
                yield i
    
    def wrap_my_generator(generator):  #定义一个包装“生成器”的生成器,它的本质还是生成器
        result=yield from generator    #自动触发StopIteration异常,并且将return的返回值赋值给yield from表达式的结果,即result
        print(result)
    
    def main(generator):
        for j in generator:
            print(j)
    
    g=my_generator()
    wrap_g=wrap_my_generator(g)
    main(wrap_g)  #调用
    '''运行结果为:
    0
    1
    我被迫中断了
    '''

    从上面的比较可以看出,yield from具有以下几个特点:

    (1)上面的my_generator是原始的生成器,main是调用方,使用yield的时候,只涉及到这两个函数,即“调用方”与“生成器(协程函数)”是直接进行交互的,不涉及其他方法,即“调用方——>生成器函数(协程函数)”

    (2)在使用yield from的时候,多了一个对原始my_generator的包装函数,然后调用方是通过这个包装函数(后面会讲到它专有的名词)来与生成器进行交互的,即“调用方——>生成器包装函数——>生成器函数(协程函数)”;

    (3)yield from iteration结构会在内部自动捕获 iteration生成器的StopIteration 异常。这种处理方式与 for 循环处理 StopIteration 异常的方式一样。而且对 yield from 结构来说,解释器不仅会捕获 StopIteration 异常,还会把return返回的值或者是StopIteration的value 属性的值变成 yield from 表达式的值,即上面的result。

    2、yield from所实现的数据传输通道

    前面总结的几个特点里面已经介绍了yield和yield from的数据交互方式,yield涉及到“调用方与生成器两者”的交互,生成器通过next()的调用将值返回给调用者,而调用者通过send()方法向生成器发送数据;

    但是yield还有一个第三者函数,下面将先从相关的概念说起。

    在PEP 380 使用了一些yield from使用的专门术语:

    委派生成器:包含 yield from <iterable> 表达式的生成器函数;即上面的wrap_my_generator生成器函数

    子生成器:从 yield from 表达式中 <iterable> 部分获取的生成器;即上面的my_generator生成器函数

    调用方:调用委派生成器的客户端代码;即上面的main生成器函数

    下图是这三者之间的交互关系(摘自博客园):

    委派生成器在 yield from 表达式处暂停时,调用方可以直接把数据发给子生成器,子生成器再把产出的值发给调用方。子生成器返回之后,解释器会抛出StopIteration 异常,并把返回值附加到异常对象上,此时委派生成器会恢复。

    总结:

    (1)yield from主要设计用来向子生成器委派操作任务,但yield from可以向任意的可迭代对象委派操作;

    (2)委派生成器(group)相当于管道,所以可以把任意数量的委派生成器连接在一起---一个委派生成器使用yield from 调用一个子生成器,而那个子生成器本身也是委派生成器,使用yield from调用另一个生成器。

    3、针对yield存在的第二个缺点

    首先看一下他要表述的意思是什么?它的局限性在于只能向它的直接调用者每次yield一个值。这意味着那些包含yield的代码不能像其他代码那样被分离出来放到一个单独的函数中。这也正是yield from要解决的。具体参见上文:

    https://blog.csdn.net/qq_27825451/article/details/85234610

    这句话确实难以理解,但是他要表达的意思实际上是:因为生成器从定义上来看,就像是一个普通的函数,那么既然作为普通函数,就应该可以反反复复调用都没问题的,但是生成器却并不行。那为什么yield from可以解决这样的问题呢,主要是因为yield from后面可以跟任意一个生成器,即yield from可以将任意的任务为派给任意生成器函数,从而避免了子生成器直接向调用者返回单个值的情况。

    (备注:这一块感觉自己也并不是理解的特别清楚,哪位大神看见,希望可以不吝赐教)

    三、yield from的用法示例

    其实yield from最重要的作用就是提供了一个“数据传输的管道”,下面通过一个简单的例子加以说明为什么是管道:

    def average():
        total = 0.0  #数字的总和
        count = 0    #数字的个数
        avg = None   #平均值
        while True:
            num = yield avg
            total += num
            count += 1
            avg = total/count
    
    def wrap_average(generator):
        yield from generator
    
    #定义一个函数,通过这个函数向average函数发送数值
    def main(wrap):
        print(next(wrap))  #启动生成器
        print(wrap.send(10))  # 10
        print(wrap.send(20))  # 15
        print(wrap.send(30))  # 20
        print(wrap.send(40))  # 25
      
    g = average()
    wrap=wrap_average(g)
    main(wrap)
     
    '''运行结果为:
    None
    10.0
    15.0
    20.0
    25.0
    '''

    从上面我们可以发现,调用方发送的数据是发给wrap_average的,怎么依然到了生成器函数average里面呢?这就是“数据传输管道的作用”。即主函数调用方main把各个value传给grouper ,而这个传入的值最终到达averager函数中; grouper并不知道传入的是什么值,因为从上面的代码看出,wrap_average里面完全没有处理这个值的任何代码!

    现在是不是对“数据传输管道”更加理解了呢?

    展开全文
  • 数仓工具—Hive语法之with as和from (4)

    万次阅读 2021-01-01 08:23:58
    1. with as 和from 可以简化SQL的写法和视图的作用有点像 2. 可以提高性能——减少表的扫描次数(缓存结果集的方式) 3. 当一个查询结果需要多次使用的时候我们就可以使用with as 这种方式,再特殊一点的场景我们也可以...
  • Chrome中的from memory cache与from disk cache

    千次阅读 2019-03-21 13:49:36
    文章目录前言一、浏览器Network的Size列二、三级缓存原理三、HTTP状态码及区别四、不同浏览器资源加载策略 前言 在Chrome开发者工具页面中,有...from memory cache from disk cache 资源本身大小(比如:13.6K) ...
  • from memory cache与from disk cache详解

    万次阅读 2018-06-13 21:18:35
    1.from memory cache 2.from disk cache 3.资源本身的大小(如:1.5k) 那么问题来了 1.三种区别在哪里;2.浏览器采取不同措施的原则是什么;3.其他浏览器的策略 下面分别讲述以上三个问题 1.三种区别在哪 from...
  • 1.from memory cache 2.from disk cache 3.资源本身的大小(如:1.5k) 那么问题来了 1.三种区别在哪里;2.浏览器采取不同措施的原则是什么;3.其他浏览器的策略 下面分别讲述以上三个问题 1.三种区别在哪 from memory...
  • Oracle Copy From命令

    千次阅读 2019-04-10 00:06:30
    一 用途 Copy 命令是SQL*Plus命令,可用于在ORACLE数据库、非ORACLE数据库之间数据...usage: COPY FROM <db> TO <db> <opt> <table> { (<cols>) } USING <sel> <db> :...
  • Dockerfile文件-FROM指定基础镜像

    千次阅读 2021-01-13 09:55:04
    1 FROM 不写会报错 2 FROM 运行一次就可以了 第二次Docker images 查看镜像id,写到FROM后,例如: FROM b7dff675qwe As build Posted bysimappleon 2014-08-12 FROM指定基础镜像 FROM <image> 或 ...
  • create table select from 和 insert into table select from都是用来复制表,两者的主要区别为: create table select from 要求目标表不存在,因为在插入时会自动创建。 insert into table select from 要求目标...
  • 文章目录一,函数二,参数说明三,方法四,示例五,使用SelectFromModel和LassoCV选择特征 一,函数 class sklearn.feature_selection.SelectFromModel(estimator, *, threshold=None, prefit=False, norm_order=...
  • Content not from webpack is served from ... 404s will fallback to / Starting the development server... 网上的说法很多,但是经笔者亲身经历之后,发现其实是电脑本身配置的问题,下面列出具体的修改方案:...
  • Python 中 raise 和 raise/from 的区别

    千次阅读 2018-11-21 11:50:15
    Python 中 raise 和 raise/from 的使用方法 文章目录Python 中 raise 和 raise/from 的使用方法0. 参考资料1. 代码比较2. 用法解释2.1 raise2.2 raise A from B3. 总结 0. 参考资料 Python “raise from” ...
  • js Array.from妙用

    万次阅读 2021-04-06 15:03:27
    var arr = Array.from(str); set转数组 const set = new Set([1,1,2,3]); Array.form(set); map转数组 const mapper = new Map([['name','mike'],['age',11]]); var keysArr = Array.from(mapper.values());// ...
  • 老版本Docker中为什么不支持多个 FROM 指令 Docker 17.05版本以后,新增了Dockerfile多阶段构建。所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个FROM指令。这样做有什么意义呢? 老版本Docker中为什么不...
  • ## # ## 微信分享后地址会自动添加from=timeline或from=singlemessage导致分享的页面无法打开! 安卓手机测试: 1. 朋友圈 from=timeline 2. 微信群 from=groupmessage 3. 好友分享 from=singlemessage 在...
  • [FromBody]与[FromForm]区别

    千次阅读 2019-09-19 08:59:10
    [FromBody]与[FromForm]区别 1,fromBody:在cation方法传入参数后添加[frombody]属性,参数将以一个整体的josn对象的形式传递。 2,fromform:在cation方法传入参数后添加[frombody]属性,参数将以表单的形式提交。...
  • numpy报ValueError: could not broadcast input array from shape

    万次阅读 多人点赞 2019-12-11 10:28:33
    问题描述 在使用numpy将list转为array的时候报错 代码 a = np.array([[1,2],[3,4]]) b = np.array([[5,6,7],[8,9,10]]) ...ValueError: could not broadcast input array from shape (2,2) into ...
  • 在刷笔试题的时候看到一个表的复制的问题,以前没见过,写一下。...1. insert into tableName2(column_name1,column_name2,....) selectcolumn_name1,column_name2,....from tableName1; 或者 insert ...
  • Tensorflow Dataset.from_generator使用示例

    万次阅读 2018-06-06 18:38:49
    最近在实际使用中越发感觉到这个方式非常好用,尤其是发现了.from_generator这个method。 关于Dataset.from_generator的简单介绍,请参见如下两个链接:...
  • 复制表(含数据): create table table_name2 as select * from table_name1 复制表(不含数据): create table table_name2 as select * from table_name1where 1=2 只复制表数据:insert into table_name2 select ...
  • SQL命令之FROM子句

    千次阅读 2020-03-07 09:20:55
    FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,之间用逗号分隔。        在FROM子句同时指定多个表或视图时,如果选择列表中存在同...
  • .Net Core中Get请求接口的参数一般可以在url中获取,但是Post请求接口一般建议使用[FromBody]特性来绑定参数,而前端发请求时也得需要注意,前端代码如下(vue): const postData = { id: 12 }; // post请求的数据...
  • Empty reply from server

    千次阅读 2018-07-23 14:18:11
    git 提交文件提示Empty reply from server 处理方法: git fetch origin --prune
  • 用赋值代替 protobuf CopyFrom()

    万次阅读 2019-04-04 17:54:13
    用赋值代替 protobuf CopyFrom() 示例:Replace protobuf CopyFrom with assignment protobuf 生成的 C++ 代码中,因为 CopyFrom() 可以接受任何 Message 作为参数, 所以有可能在2个不同类型的消息之间复制。 void...
  • import、from...improt、from...import *三者的区别

    万次阅读 多人点赞 2018-10-21 21:14:55
    首先你要了解 import 与 from…import 的区别。 import 模块:导入一个模块;注:相当于导入的是一个文件夹,是个相对路径。 from…import:导入了一个模块中的一个函数;注:相当于导入的是一个文件夹中的文件,...
  • ImportError: cannot import name 'imread' from 'scipy.misc' (D:\Program Files (x86)\Python37\lib\site-packages\scipy\misc\__init__.py) ``` 已经从网上找了很多帖子关于此问题,但都未能解决,求各位大大...
  • Dockerfile的FROM 和 ARG指令

    万次阅读 2018-01-10 20:49:14
    FROM三种格式 FROM [AS ] FROM [:] [AS ] FROM [@] [AS ] 二 ARG是唯一一个可用于FROM前的指令 1 示例 ARG CODE_VERSION=latest FROM base:${CODE_VERSION} CMD /code/run-app FROM extras:${CODE...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,741,029
精华内容 3,096,411
关键字:

from