精华内容
参与话题
问答
  • python的with用法

    万次阅读 2016-10-06 21:18:11
    1.With语句是什么?有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭...

    项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
    欢迎大家star,留言,一起学习进步

    1.With语句是什么?

    有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。

    如果不用with语句,代码如下:

    file = open("/tmp/foo.txt")
    data = file.read()
    file.close()
    

    这里有两个问题:

    一是可能忘记关闭文件句柄;
    二是文件读取数据发生异常,没有进行任何处理。

    下面是处理异常的加强版本:

    try:
        f = open('xxx')
    except:
        print 'fail to open'
        exit(-1)
    try:
        do something
    except:
        do something
    finally:
         f.close()
    

    虽然这段代码运行良好,但是太冗长了。

    这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。

    下面是with版本的代码:

    with open("/tmp/foo.txt") as file:
        data = file.read()
    

    2.with如何工作?

    紧跟with后面的语句被求值后,返回对象的 _enter_() 方法被调用,这个方法的返回值将被赋值给as后面的变量。
    当with后面的代码块全部被执行完之后,将调用前面返回对象的 _exit_()方法。

    下面例子可以具体说明with如何工作:

    #!/usr/bin/env python
    # with_example01.py
    class Sample:
        def __enter__(self):
            print "In __enter__()"
            return "Foo"
        def __exit__(self, type, value, trace):
            print "In __exit__()"
    def get_sample():
        return Sample()
    with get_sample() as sample:
        print "sample:", sample
    

    运行代码,输出如下

    bash-3.2$ ./with_example01.py
    In __enter__()
    sample: Foo
    In __exit__()
    

    正如你看到的: 1. _enter_()方法被执行 2. _enter_()方法返回的值 - 这个例子中是”Foo”,赋值给变量’sample’ 3. 执行代码块,打印变量”sample”的值为 “Foo” 4. _exit_()方法被调用
    with真正强大之处是它可以处理异常。可能你已经注意到Sample类的 _exit_ 方法有三个参数 val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。

    #!/usr/bin/env python
    # with_example02.py
    class Sample:
        def __enter__(self):
            return self
        def __exit__(self, type, value, trace):
            print "type:", type
            print "value:", value
            print "trace:", trace
        def do_something(self):
            bar = 1/0
            return bar + 10
    with Sample() as sample:
        sample.do_something()
    

    这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有 _enter_() 和 _exit_() 方法即可。此例中,Sample()的 _enter_() 方法返回新创建的Sample对象,并赋值给变量sample。

    代码执行后:

    bash-3.2$ ./with_example02.py
    type: <type 'exceptions.ZeroDivisionError'>
    value: integer division or modulo by zero
    trace: <traceback object at 0x1004a8128>
    Traceback (most recent call last):
      File "./with_example02.py", line 19, in <module>
        sample.do_something()
      File "./with_example02.py", line 15, in do_something
        bar = 1/0
    ZeroDivisionError: integer division or modulo by zero
    

    实际上,在with后面的代码块抛出任何异常时,_exit_() 方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给 _exit_() 方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在 _exit_ 方法当中。

    另外,_exit_ 除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。

    下面的样例代码跳过了所有的TypeError,而让其他异常正常抛出。

    def __exit__(self, type, value, traceback):
        return isinstance(value, TypeError)
    

    上文说了 _exit_ 函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):

    try:
        with open( "a.txt" ) as f :
            do something
    except xxxError:
        do something about exception
    

    总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。

    如果有多个项,我们可以这么写:

    with open("x.txt") as f1, open('xxx.txt') as f2:
        do something with f1,f2
    

    因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。

    3.相关术语

    要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。
    下面是一组与上下文管理器和with 语句有关的概念。
    上下文管理协议(Context Management Protocol):包含方法 _enter_() 和 _exit_(),支持该协议的对象要实现这两个方法。
    上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了_enter_() 和 _exit_() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,也可以通过直接调用其方法来使用。
    运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 _enter_() 和_exit_() 方法实现,_enter_() 方法在语句体执行之前进入运行时上下文,_exit_() 在语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这一概念。
    上下文表达式(Context Expression):with 语句中跟在关键字 with 之后的表达式,该表达式要返回一个上下文管理器对象。
    语句体(with-body):with 语句包裹起来的代码块,在执行语句体之前会调用上下文管理器的 _enter_() 方法,执行完语句体之后会执行_exit_() 方法。

    相关链接:
    1.http://blog.kissdata.com/2014/05/23/python-with.html
    2.https://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/

    展开全文
  • 详解python中的with关键字

    千次阅读 2018-08-30 01:14:39
    对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。 如何正确的关闭一个文件呢? 1.普通版 def test0(): ...

    对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。

    如何正确的关闭一个文件呢?

    1.普通版

    def test0():
        f = open("1.txt", "w")
        f.write("0000")
        f.close()

    2.进阶版

    def test1():
        f = open("1.txt", "w")
        try:
            f.write("111111")
        except Exception:
            print("ERROR")
        finally:
            f.close()

    3.高级版

    def test2():
        with open("1.txt", "w") as f:
            f.write("2222")
    使用with关键字的方法更为简洁,它的实现原理是什么,这就涉及到上下文管理器。

    任何实现了 __enter__()__exit__() 方法的对象都可称之为上下文管理器

    4.用类还原with的实现原理

    class Test4(object):
        def __init__(self, file_name, mode):
            self.file_name = file_name
            self.mode = mode
        def __enter__(self):
            self.f = open(self.file_name, self.mode)
            return self.f
        def __exit__(self,*args):
            self.f.close()
    with Test4("1.txt", "w") as f:
        f.write("4444")
    """
    首先Test4("1.txt", "w")初始化实例对象,
    然后with会寻找类中是否有__enter__  和 __exit__,
    如果有则调用__enter__函数,
    最后__enter__() 方法返回资源对象,这里就是你将要打开
    的那个文件对象,__exit__() 方法处理一些清除工作。
    """

    5.使用contextmanager装饰器,实现with功能

    from contextlib import contextmanager
    """
    Python 还提供了一个 contextmanager 的装饰器,更进一步简化
    了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 之前的
    语句在 __enter__ 方法中执行,yield 之后的语句在 __exit__ 方法中执行。
    紧跟在 yield 后面的值是函数的返回值。
    """
    @contextmanager
    def test5(path, mode):
        f = open(path, mode)
        yield f
        f.close()
    with test5('out.txt', 'w') as f:
        f.write("5555")
    总结:

    Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上。此外,Python 还提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式。

    展开全文
  • Python 中 with用法及原理

    万次阅读 多人点赞 2017-06-08 11:22:17
    前言with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等。

    前言

    with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等。

    问题引出

    如下代码:

    file = open("1.txt")
    data = file.read()
    file.close()

    上面代码存在2个问题:
    (1)文件读取发生异常,但没有进行任何处理;
    (2)可能忘记关闭文件句柄;

    改进

    try:
        f = open('xxx')
    except:
        print('fail to open')
        exit(-1)
    try:
        do something
    except:
        do something
    finally:
        f.close()

    虽然这段代码运行良好,但比较冗长。
    而使用with的话,能够减少冗长,还能自动处理上下文环境产生的异常。如下面代码:

    with open("1.txt") as file:
        data = file.read()

    with 工作原理

    (1)紧跟with后面的语句被求值后,返回对象的“–enter–()”方法被调用,这个方法的返回值将被赋值给as后面的变量;
    (2)当with后面的代码块全部被执行完之后,将调用前面返回对象的“–exit–()”方法。
    with工作原理代码示例:

    class Sample:
        def __enter__(self):
            print "in __enter__"
            return "Foo"
        def __exit__(self, exc_type, exc_val, exc_tb):
            print "in __exit__"
    def get_sample():
        return Sample()
    with get_sample() as sample:
        print "Sample: ", sample

    代码的运行结果如下:

    in __enter__
    Sample:  Foo
    in __exit__

    可以看到,整个运行过程如下:
    (1)enter()方法被执行;
    (2)enter()方法的返回值,在这个例子中是”Foo”,赋值给变量sample;
    (3)执行代码块,打印sample变量的值为”Foo”;
    (4)exit()方法被调用;

    【注:】exit()方法中有3个参数, exc_type, exc_val, exc_tb,这些参数在异常处理中相当有用。
    exc_type: 错误的类型
    exc_val: 错误类型对应的值
    exc_tb: 代码中错误发生的位置
    示例代码:

    class Sample():
        def __enter__(self):
            print('in enter')
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print "type: ", exc_type
            print "val: ", exc_val
            print "tb: ", exc_tb
        def do_something(self):
            bar = 1 / 0
            return bar + 10
    with Sample() as sample:
        sample.do_something()

    程序输出结果:

    in enter
    Traceback (most recent call last):
    type:  <type 'exceptions.ZeroDivisionError'>
    val:  integer division or modulo by zero
      File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 36, in <module>
    tb:  <traceback object at 0x7f9e13fc6050>
        sample.do_something()
      File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 32, in do_something
        bar = 1 / 0
    ZeroDivisionError: integer division or modulo by zero
    
    Process finished with exit code 1

    总结

    实际上,在with后面的代码块抛出异常时,exit()方法被执行。开发库时,清理资源,关闭文件等操作,都可以放在exit()方法中。
    总之,with-as表达式极大的简化了每次写finally的工作,这对代码的优雅性是有极大帮助的。
    如果有多项,可以这样写:

    With open('1.txt') as f1, open('2.txt') as  f2:
        do something

    参考网址

    http://blog.kissdata.com/2014/05/23/python-with.html

    展开全文
  • 关于SQL语句中With的用法

    万次阅读 2017-02-16 14:04:28
    创建和使用 CTE 的指南 下列指南应用于非递归 CTE。有关适用于递归 CTE 的指南,请参阅后面的“定义和使用递归 CTE 的指南”。 CTE 之后必须跟随引用部分或全部 CTE 列的 SELECT、INSERT、UPDATE 或 DELETE ...

    创建和使用 CTE 的指南

    下列指南应用于非递归 CTE。有关适用于递归 CTE 的指南,请参阅后面的“定义和使用递归 CTE 的指南”。

    • CTE 之后必须跟随引用部分或全部 CTE 列的 SELECT、INSERT、UPDATE 或 DELETE 语句。也可以在 CREATE VIEW 语句中将 CTE 指定为视图中 SELECT 定义语句的一部分。
    • 可以在非递归 CTE 中定义多个 CTE 查询定义。定义必须与以下集合运算符之一结合使用:UNION ALL、UNION、INTERSECT 或 EXCEPT。
    • CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。
    • 不允许在一个 CTE 中指定多个 WITH 子句。例如,如果 CTE_query_definition 包含一个子查询,则该子查询不能包括定义另一个 CTE 的嵌套的 WITH 子句。
    • 不能在 CTE_query_definition 中使用以下子句:

      • COMPUTE 或 COMPUTE BY
      • ORDER BY(除非指定了 TOP 子句)
      • INTO
      • 带有查询提示的 OPTION 子句
      • FOR XML
      • FOR BROWSE
    • 如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾。
    • 可以使用引用 CTE 的查询来定义游标。
    • 可以在 CTE 中引用远程服务器中的表。
    • 在执行 CTE 时,任何引用 CTE 的提示都可能与该 CTE 访问其基础表时发现的其他提示相冲突,这种冲突与引用查询中的视图的提示所发生的冲突相同。发生这种情况时,查询将返回错误。有关详细信息,请参阅视图解析。

    定义和使用递归 CTE 指南

    下列指南适用于定义递归 CTE 的情况:

    • 递归 CTE 定义至少必须包含两个 CTE 查询定义,一个定位点成员和一个递归成员。可以定义多个定位点成员和递归成员;但必须将所有定位点成员查询定义置于第一个递归成员定义之前。所有 CTE 查询定义都是定位点成员,但它们引用 CTE 本身时除外。
    • 定位点成员必须与以下集合运算符之一结合使用:UNION ALL、UNION、INTERSECT 或 EXCEPT。在最后一个定位点成员和第一个递归成员之间,以及组合多个递归成员时,只能使用 UNION ALL 集合运算符。
    • 定位点成员和递归成员中的列数必须一致。
    • 递归成员中列的数据类型必须与定位点成员中相应列的数据类型一致。
    • 递归成员的 FROM 子句只能引用一次 CTE expression_name。
    • 在递归成员的 CTE_query_definition 中不允许出现下列项:

      • SELECT DISTINCT
      • GROUP BY
      • HAVING
      • 标量聚合
      • TOP
      • LEFT、RIGHT、OUTER JOIN(允许出现 INNER JOIN)
      • 子查询
      • 应用于对 CTE_query_definition 中的 CTE 的递归引用的提示。

    下列指南适用于使用递归 CTE:

    • 无论参与的 SELECT 语句返回的列的为空性如何,递归 CTE 返回的全部列都可以为空。
    • 如果递归 CTE 组合不正确,可能会导致无限循环。例如,如果递归成员查询定义对父列和子列返回相同的值,则会造成无限循环。可以使用 MAXRECURSION 提示以及在 INSERT、UPDATE、DELETE 或 SELECT 语句的 OPTION 子句中的一个 0 到 32,767 之间的值,来限制特定语句所允许的递归级数,以防止出现无限循环。这样就能够在解决产生循环的代码问题之前控制语句的执行。服务器范围内的默认值是 100。如果指定 0,则没有限制。每一个语句只能指定一个 MAXRECURSION 值。有关详细信息,请参阅查询提示 (Transact-SQL)
    • 不能使用包含递归公用表表达式的视图来更新数据。
    • 可以使用 CTE 在查询上定义游标。递归 CTE 只允许使用快速只进游标和静态(快照)游标。如果在递归 CTE 中指定了其他游标类型,则该类型将转换为静态游标类型。
    • 可以在 CTE 中引用远程服务器中的表。如果在 CTE 的递归成员中引用了远程服务器,那么将为每个远程表创建一个假脱机,这样就可以在本地反复访问这些表。

    参数

    expression_name

    公用表表达式的有效标识符。 expression_name 必须与在同一 WITH <common_table_expression> 子句中定义的任何其他公用表表达式的名称不同,但 expression_name 可以与基表或基视图的名称相同。在查询中对 expression_name 的任何引用都会使用公用表表达式,而不使用基对象。

    column_name

    在公用表表达式中指定列名。在一个 CTE 定义中不允许出现重复的名称。指定的列名数必须与 CTE_query_definition 结果集中列数匹配。只有在查询定义中为所有结果列都提供了不同的名称时,列名称列表才是可选的。

    CTE_query_definition

    指定一个其结果集填充公用表表达式的 SELECT 语句。除了 CTE 不能定义另一个 CTE 以外,CTE_query_definition 的 SELECT 语句必须满足与创建视图时相同的要求。有关详细信息,请参阅“备注”部分和 CREATE VIEW (Transact-SQL)

    如果定义了多个 CTE_query_definition,则这些查询定义必须用下列一个集合运算符联接起来:UNION ALL、UNION、EXCEPT 或 INTERSECT。有关使用递归 CTE 查询定义的详细信息,请参阅下列“备注”部分和使用公用表表达式的递归查询。

    示例

    A. 创建一个简单公用表表达式

    以下示例显示直接向 Adventure Works Cycles 的每个经理报告的雇员的数目。

      复制代码
    USE AdventureWorks;
    GO
    WITH DirReps(ManagerID, DirectReports) AS 
    (
        SELECT ManagerID, COUNT(*) 
        FROM HumanResources.Employee AS e
        WHERE ManagerID IS NOT NULL
        GROUP BY ManagerID
    )
    SELECT ManagerID, DirectReports 
    FROM DirReps 
    ORDER BY ManagerID;
    GO

    B. 使用公用表表达式来限制次数和报告平均数

    以下示例显示向经理报告的雇员的平均数。

      复制代码
    WITH DirReps (Manager, DirectReports) AS 
    (
        SELECT ManagerID, COUNT(*) AS DirectReports
        FROM HumanResources.Employee
        GROUP BY ManagerID
    ) 
    SELECT AVG(DirectReports) AS [Average Number of Direct Reports]
    FROM DirReps 
    WHERE DirectReports>= 2 ;
    GO

    C. 多次引用同一个公用表表达式

    以下示例显示 SalesOrderHeader 表中每个销售人员的销售订单的总数和最近的销售订单的日期。CTE 在运行的语句中被引用两次:一次返回为销售人员所选的列,另一次检索销售经理的类似详细信息。销售人员和销售经理的数据都返回在一行中。

      复制代码
    USE AdventureWorks;
    GO
    WITH Sales_CTE (SalesPersonID, NumberOfOrders, MaxDate)
    AS
    (
        SELECT SalesPersonID, COUNT(*), MAX(OrderDate)
        FROM Sales.SalesOrderHeader
        GROUP BY SalesPersonID
    )
    SELECT E.EmployeeID, OS.NumberOfOrders, OS.MaxDate,
        E.ManagerID, OM.NumberOfOrders, OM.MaxDate
    FROM HumanResources.Employee AS E
        JOIN Sales_CTE AS OS
        ON E.EmployeeID = OS.SalesPersonID
        LEFT OUTER JOIN Sales_CTE AS OM
        ON E.ManagerID = OM.SalesPersonID
    ORDER BY E.EmployeeID;
    GO

    使用递归公用表表达式显示递归的多个级别。

    以下示例显示经理以及向经理报告的雇员的层次列表。

      复制代码
    USE AdventureWorks;
    GO
    WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS 
    (
        SELECT ManagerID, EmployeeID, 0 AS EmployeeLevel
        FROM HumanResources.Employee
        WHERE ManagerID IS NULL
        UNION ALL
        SELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1
        FROM HumanResources.Employee e
            INNER JOIN DirectReports d
            ON e.ManagerID = d.EmployeeID 
    )
    SELECT ManagerID, EmployeeID, EmployeeLevel 
    FROM DirectReports ;
    GO

    E. 使用递归公用表表达式显示递归的两个级别。

    以下示例显示经理以及向经理报告的雇员。将返回的级别数目被限制为两个。

      复制代码
    USE AdventureWorks;
    GO
    WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS 
    (
        SELECT ManagerID, EmployeeID, 0 AS EmployeeLevel
        FROM HumanResources.Employee
        WHERE ManagerID IS NULL
        UNION ALL
        SELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1
        FROM HumanResources.Employee e
            INNER JOIN DirectReports d
            ON e.ManagerID = d.EmployeeID 
    )
    SELECT ManagerID, EmployeeID, EmployeeLevel 
    FROM DirectReports 
    WHERE EmployeeLevel <= 2 ;
    GO

    F. 使用递归公用表表达式显示层次列表

    以下示例在示例 C 的基础上添加经理和雇员的名称,以及他们各自的头衔。通过缩进各个级别,突出显示经理和雇员的层次结构。

      复制代码
    USE AdventureWorks;
    GO
    WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort)
    AS (SELECT CONVERT(varchar(255), c.FirstName + ' ' + c.LastName),
            e.Title,
            e.EmployeeID,
            1,
            CONVERT(varchar(255), c.FirstName + ' ' + c.LastName)
        FROM HumanResources.Employee AS e
        JOIN Person.Contact AS c ON e.ContactID = c.ContactID 
        WHERE e.ManagerID IS NULL
        UNION ALL
        SELECT CONVERT(varchar(255), REPLICATE ('| ' , EmployeeLevel) +
            c.FirstName + ' ' + c.LastName),
            e.Title,
            e.EmployeeID,
            EmployeeLevel + 1,
            CONVERT (varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' + 
                     LastName)
        FROM HumanResources.Employee as e
        JOIN Person.Contact AS c ON e.ContactID = c.ContactID
        JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
        )
    SELECT EmployeeID, Name, Title, EmployeeLevel
    FROM DirectReports 
    ORDER BY Sort;
    GO

    G. 使用 MAXRECURSION 取消一条语句

    可以使用 MAXRECURSION 来防止不合理的递归 CTE 进入无限循环。以下示例有意创建了一个无限循环,然后使用 MAXRECURSION 提示来将递归级别限制为两个。

      复制代码
    USE AdventureWorks;
    GO
    --Creates an infinite loop
    WITH cte (EmployeeID, ManagerID, Title) as
    (
        SELECT EmployeeID, ManagerID, Title
        FROM HumanResources.Employee
        WHERE ManagerID IS NOT NULL
      UNION ALL
        SELECT cte.EmployeeID, cte.ManagerID, cte.Title
        FROM cte 
        JOIN  HumanResources.Employee AS e 
            ON cte.ManagerID = e.EmployeeID
    )
    --Uses MAXRECURSION to limit the recursive levels to 2
    SELECT EmployeeID, ManagerID, Title
    FROM cte
    OPTION (MAXRECURSION 2);
    GO

    在更正代码错误之后,就不再需要 MAXRECURSION。以下示例显示了更正后的代码。

      复制代码
    USE AdventureWorks;
    GO
    WITH cte (EmployeeID, ManagerID, Title)
    AS
    (
        SELECT EmployeeID, ManagerID, Title
        FROM HumanResources.Employee
        WHERE ManagerID IS NOT NULL
      UNION ALL
        SELECT  e.EmployeeID, e.ManagerID, e.Title
        FROM HumanResources.Employee AS e
        JOIN cte ON e.ManagerID = cte.EmployeeID
    )
    SELECT EmployeeID, ManagerID, Title
    FROM cte;
    GO

    H. 使用公用表表达式来有选择地执行 SELECT 语句中的递归操作

    以下示例显示了为 ProductAssemblyID = 800 生产自行车所需的产品装配和部件层次结构。

      复制代码
    USE AdventureWorks;
    GO
    WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
    (
        SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
            b.EndDate, 0 AS ComponentLevel
        FROM Production.BillOfMaterials AS b
        WHERE b.ProductAssemblyID = 800
              AND b.EndDate IS NULL
        UNION ALL
        SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
            bom.EndDate, ComponentLevel + 1
        FROM Production.BillOfMaterials AS bom 
            INNER JOIN Parts AS p
            ON bom.ProductAssemblyID = p.ComponentID
            AND bom.EndDate IS NULL
    )
    SELECT AssemblyID, ComponentID, Name, PerAssemblyQty, EndDate,
            ComponentLevel 
    FROM Parts AS p
        INNER JOIN Production.Product AS pr
        ON p.ComponentID = pr.ProductID
    ORDER BY ComponentLevel, AssemblyID, ComponentID;
    GO

    I. 在 UPDATE 语句中使用递归 CTE

    以下示例将直接或间接向 ManagerID 12 报告的所有雇员的 VacationHours 值增加 25%。公用表表达式返回一个向 ManagerID 12 直接报告的雇员的层次列表,以及向这些雇员报告的雇员的层次列表,等等。只修改公用表表达式所返回的行。

      复制代码
    USE AdventureWorks;
    GO
    WITH DirectReports(EmployeeID, NewVacationHours, EmployeeLevel)
    AS
    (SELECT e.EmployeeID, e.VacationHours, 1
      FROM HumanResources.Employee AS e
      WHERE e.ManagerID = 12
      UNION ALL
      SELECT e.EmployeeID, e.VacationHours, EmployeeLevel + 1
      FROM HumanResources.Employee as e
      JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
    )
    UPDATE HumanResources.Employee
    SET VacationHours = VacationHours * 1.25
    FROM HumanResources.Employee AS e
    JOIN DirectReports AS d ON e.EmployeeID = d.EmployeeID;
    GO

    使用多个定位点和递归成员

    以下示例使用多个定位点和递归成员来返回指定的人的所有祖先。创建了一个表,并在表中插入值,以建立由递归 CTE 返回的宗谱。

      复制代码
    -- Genealogy table
    IF OBJECT_ID('Person','U') IS NOT NULL DROP TABLE Person;
    GO
    CREATE TABLE Person(ID int, Name varchar(30), Mother int, Father int);
    GO
    INSERT Person VALUES(1, 'Sue', NULL, NULL);
    INSERT Person VALUES(2, 'Ed', NULL, NULL);
    INSERT Person VALUES(3, 'Emma', 1, 2);
    INSERT Person VALUES(4, 'Jack', 1, 2);
    INSERT Person VALUES(5, 'Jane', NULL, NULL);
    INSERT Person VALUES(6, 'Bonnie', 5, 4);
    INSERT Person VALUES(7, 'Bill', 5, 4);
    GO
    -- Create the recursive CTE to find all of Bonnie's ancestors.
    WITH Generation (ID) AS
    (
    -- First anchor member returns Bonnie's mother.
        SELECT Mother 
        FROM Person
        WHERE Name = 'Bonnie'
    UNION
    -- Second anchor member returns Bonnie's father.
        SELECT Father 
        FROM Person
        WHERE Name = 'Bonnie'
    UNION ALL
    -- First recursive member returns male ancestors of the previous generation.
        SELECT Person.Father
        FROM Generation, Person
        WHERE Generation.ID=Person.ID
    UNION ALL
    -- Second recursive member returns female ancestors of the previous generation.
        SELECT Person.Mother
        FROM Generation, Person
        WHERE Generation.ID=Person.ID
    )
    SELECT Person.ID, Person.Name, Person.Mother, Person.Father
    FROM Generation, Person
    WHERE Generation.ID = Person.ID;
    GO
    展开全文
  • Python中打开文件的方式(With open)

    万次阅读 多人点赞 2018-08-05 19:53:16
    python文件读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘...
  • with

    2019-04-09 20:56:00
    内存里的资源有 垃圾回收机制 ...非内存资源必须手动释放 用 with 关闭 还有今天学的tcp协议的 sk.close() with : return 不会打断 正常关闭 转载于:https://www.cnblogs.com/Doner/p/10679679.html...
  • JavaScript中 with的用法

    万次阅读 多人点赞 2018-03-28 12:50:09
      说起js中的with关键字,很多小伙伴们的第一印象可能就是with关键字的作用在于改变作用域,然后最关键的一点是不推荐使用with关键字。听到不推荐with关键字后,我们很多人都会忽略掉with关键字,认为不要去管它用...
  • python with用法

    万次阅读 2011-10-27 13:28:04
    python中with可以明显改进代码友好度,比如: with open('a.txt') as f: print f.readlines() 为了我们自己的类也可以使用with, 只要给这个类增加两个函数__enter__, __exit__即可: >>> class A: def __enter...
  • with with open(file='HelloWorld', mode='r')as f: print(f.read()) 没用with import traceback f = open(file='HelloWorld', mode='w') try: f.write('world: go away') except: print(traceback.format...
  • k8s v1.15.x部署This week I’ve had the pleasure of dealing with lots of wireless (WLAN) de-authentication attacks on my Wireless AP’s (WAPs) with attempts to crack my WPA2 key. The reason why I found...
  • Python-with open() as f的用法

    万次阅读 多人点赞 2019-02-01 21:48:15
    with open(r'filename.txt') as f: data_user=pd.read_csv(f) #文件的读操作 with open('data.txt', 'w') as f: f.write('hello world') #文件的写操作 相关参数: r: 以只读方式打开文件。文件的指针将会放在...
  • python 使用 with open() as 读写文件

    万次阅读 多人点赞 2018-08-24 16:06:45
    要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符: &gt;&gt;&gt; f = open('E:\python\python\test.txt', 'r') 标示符'r'表示读,这样,我们就成功地打开了一个...
  • Python文件操作,with open as追加文本内容实例

    万次阅读 多人点赞 2017-07-25 11:12:56
    with open('/Users/Mr.Long/Desktop/data.txt', 'w') as f: f.write('hello world') 就这样就完成了文件的写操错(此处用with的格式,可以节省很多不必要的麻烦) 读操作同理,只是做一下微小的变化处理而已 with...
  • Python中with以及with open的用法

    千次阅读 2019-06-04 17:01:43
    with open语句用法: 由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try … finally来实现: try: f = ope...
  • python-with open函数的用法

    万次阅读 2019-06-28 11:04:17
    open() 函数返回一个file object,通常需要传入两个参数 filename和mode—— open(filename, mode). f = open(‘workfile’, ‘w’) 第一个参数filename是包含文件地址的str 第二个参数mode用来指定文件被使用的方式...
  • with open使用方法

    万次阅读 2017-08-02 16:08:02
    昨晚在级群有个同学提出一个问题需要去读文件每一行的倒数18个字符并写到另一个文件中,一开始以为用Python三行代码应该能够解决,但写了二十分钟才真正解决问题。 首先需要知道的是要使用到两个...with open(r'D:\p
  • with open() as f 用法

    万次阅读 2019-09-28 18:26:05
    with open(r'filename.txt') as f: data_user=pd.read_csv(f) #文件的读操作 with open('data.txt', 'w') as f: f.write('hello world') #文件的写操作 相关参数: r: 以只读方式打开文件。文件的指针将会放在...
  • with open 总是用不了,无论怎样都会报错语法错误 ``` import requests url = 'https://pic.qiushibaike.com/system/pictures/12292/122926302/medium/O6Z3BIKE39GTB6OM.jpg' img_data = requests.get(url = url...
  • with open(self.userList,'r') as f_username: UserListCount=len(list(f_username)) print(UserListCount) with open(self.passList,'r') as f_password : for name in f_username: *****************...
  • python文件读写,以后就用with open语句

    千次阅读 2018-06-25 16:32:30
    Python内置了读写文件的函数,用法和C是兼容的。读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一...
  • with open完成python读写

    千次阅读 2017-11-13 16:25:33
    python文件读写,以后就用with open语句 读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代...
  • python 中 openwith open 的区别

    千次阅读 2019-01-12 14:42:56
    python文件读写,以后就用with open语句 读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不...
  • python读取文件之with open()

    千次阅读 2019-11-28 13:59:12
    open()VS with open() 目前最常使用的是with open()函数,首先介绍它和open()的区别: open()完成后必须调用close()方法关闭文件,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件...
  • https://blog.csdn.net/charuiyu/article/details/86360453
  • open()和with open() as的区别

    万次阅读 2018-10-11 14:33:42
    file = open("test.txt","r") for line in file.readlines(): print line file.close() 这样直接打开文件,...with open("test.txt","r") as file: for line in file....
  • with open()as filename

    千次阅读 2018-04-10 18:52:46
    使用文件用with的好处 1.会在运行完后自动关闭文件 ...with open('c.xls','r') as t1: content = t1.read() print(content) with open('c.xls','r') as t1: content = t1.read() con = t1.readline...
  • open() open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) # 默认读取整个文件,即:所有字符 f = open('C:/Users/xxx/Desktop/测试读取文件.txt', 'r...
  • with open()用法

    2019-11-25 22:38:54
    with open(r'filename.txt') as f: data_user=pd.read_csv(f) #文件的读操作 with open('data.txt', 'w') as f: f.write('hello world') #文件的写操作 r: 以只读方式打开文件。文件的指针将会放在文件的开头...
  • python with open读取

    2019-03-28 12:51:52
    with open("urls.txt",'r') as f:
  • Python中关于with open file as 的用法

    万次阅读 2015-04-23 18:57:42
    发现python中提供的with open as 这个还是用的不错的!好的,废话不多说了,看下例子: with open('./sigir_title_cizu.txt') as cizu, open('sigir_title.txt') as titles: cizuData = cizu.readlines() title

空空如也

1 2 3 4 5 ... 20
收藏数 4,291,812
精华内容 1,716,724
关键字:

with