精华内容
下载资源
问答
  • 我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。大部分留言,我都在相对应...
    4b88f49eda832b4a3df9ab47dad272fa.png

    我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。

    大部分留言,我都在相对应的文章中回复过了。而一些手机上不方便回复,或是很有价值很典型的问题,我专门摘录了出来,作为今天的答疑内容,集中回复。

    问题一:列表 self append 无限嵌套的原理

    678190a44f5c403701f6e22b5e4329c3.png

    先来回答第一个问题,两个同学都问到了,下面这段代码中的 x,为什么是无限嵌套的列表?

    x = [1]x.append(x)x[1, [...]]复制代码

    我们可以将上述操作画一个图,便于你更直观地理解:

    8831140565c8034782b58c6313b685ea.png

    这里,x 指向一个列表,列表的第一个元素为 1;执行了 append 操作后,第二个元素又反过来指向 x,即指向了 x 所指向的列表,因此形成了一个无限嵌套的循环:[1, [1, [1, [1, …]]]]。

    不过,虽然 x 是无限嵌套的列表,但 x.append(x) 的操作,并不会递归遍历其中的每一个元素。它只是扩充了原列表的第二个元素,并将其指向 x,因此不会出现 stack overflow 的问题,自然不会报错。

    至于第二点,为什么 len(x) 返回的是 2?我们还是来看 x,虽然它是无限嵌套的列表,但 x 的 top level 只有 2 个元素组成,第一个元素为 1,第二个元素为指向自身的列表,因此 len(x) 返回 2。

    问题二:装饰器的宏观理解

    67724eaede9560279f63c180ce169240.png

    再来看第二个问题,胡峣同学对装饰器的疑问。事实上,装饰器的作用与意义,在于其可以通过自定义的函数或类,在不改变原函数的基础上,改变原函数的一些功能。

    Decorators is to modify the behavior of the function through a wrapper so we don't have to actually modify the function.复制代码

    装饰器将额外增加的功能,封装在自己的装饰器函数或类中;如果你想要调用它,只需要在原函数的顶部,加上 @decorator 即可。显然,这样做可以让你的代码得到高度的抽象、分离与简化。

    光说概念可能还是有点抽象,我们可以想象下面这样一个场景,从真实例子来感受装饰器的魅力。在一些社交网站的后台,有无数的操作在调用之前,都需要先检查用户是否登录,比如在一些帖子里发表评论、发表状态等等。

    如果你不知道装饰器,用常规的方法来编程,写出来的代码大概是下面这样的:

    # 发表评论def post_comment(request, ...):    if not authenticate(request):        raise Exception('U must log in first')    ...    # 发表状态def post_moment(request, ...):    if not authenticate(request):        raise Exception('U must log in first')    ...复制代码

    显然,这样重复调用认证函数 authenticate() 的步骤,就显得非常冗余了。更好的解决办法,就是将认证函数 authenticate() 单独分离出来,写成一个装饰器,就像我们下面这样的写法。这样一来,代码便得到了高度的优化:

    # 发表评论@authenticatedef post_comment(request, ...): # 发表状态@authenticatedef post_moment(request, ...):复制代码

    不过也要注意,很多情况下,装饰器并不是唯一的方法。而我这里强调的,主要是使用装饰器带来的好处:

    • 代码更加简洁;
    • 逻辑更加清晰;
    • 程序的层次化、分离化更加明显。

    而这也是我们应该遵循和优先选择的开发模式。

    问题三:GIL 与多线程的关系

    8047933ca4c433d10f84b9311b784530.png

    第三个问题,new 同学疑惑的是,GIL 只支持单线程,而 Python 支持多线程,这两者之间究竟是什么关系呢?

    其实,GIL 的存在与 Python 支持多线程并不矛盾。前面我们讲过,GIL 是指同一时刻,程序只能有一个线程运行;而 Python 中的多线程,是指多个线程交替执行,造成一个“伪并行”的结果,但是具体到某一时刻,仍然只有 1 个线程在运行,并不是真正的多线程并行。这个机制,我画了下面这张图来表示:

    bad12a7b49b7d1d722d2fecfef175c14.png

    举个例子来理解。比如,我用 10 个线程来爬取 50 个网站的内容。线程 1 在爬取第 1 个网站时,被 I/O block 住了,处于等待状态;这时,GIL 就会释放,而线程 2 就会开始执行,去爬取第 2 个网站,依次类推。等到线程 1 的 I/O 操作完成时,主程序便又会切回线程 1,让其完成剩下的操作。这样一来,从用户角度看到的,便是我们所说的多线程。

    问题四:多进程与多线程的应用场景

    8cf831c98d8646fb64132f24e0ae0125.png

    第四个问题,这个在文章中多次提到,不过,我还是想在这里再次强调一下。

    如果你想对 CPU 密集型任务加速,使用多线程是无效的,请使用多进程。这里所谓的 CPU 密集型任务,是指会消耗大量 CPU 资源的任务,比如求 1 到 100000000 的乘积,或者是把一段很长的文字编码后又解码等等。

    使用多线程之所以无效,原因正是我们前面刚讲过的,Python 多线程的本质是多个线程互相切换,但同一时刻仍然只允许一个线程运行。因此,你使用多线程,和使用一个主线程,本质上来说并没有什么差别;反而在很多情况下,因为线程切换带来额外损耗,还会降低程序的效率。

    而如果使用多进程,就可以允许多个进程之间 in parallel 地执行任务,所以能够有效提高程序的运行效率。

    至于 I/O 密集型任务,如果想要加速,请优先使用多线程或 Asyncio。当然,使用多进程也可以达到目的,但是完全没有这个必要。因为对 I/O 密集型任务来说,大多数时间都浪费在了 I/O 等待上。因此,在一个线程 / 任务等待 I/O 时,我们只需要切换线程 / 任务去执行其他 I/O 操作就可以了。

    不过,如果 I/O 操作非常多、非常 heavy,需要建立的连接也比较多时,我们一般会选择 Asyncio。因为 Asyncio 的任务切换更加轻量化,并且它能启动的任务数也远比多线程启动的线程数要多。当然,如果 I/O 的操作不是那么的 heavy,那么使用多线程也就足够了。

    今天主要回答这几个问题,同时也欢迎你继续在留言区写下疑问和感想,我会持续不断地解答。希望每一次的留言和答疑,都能给你带来新的收获和价值。

    展开全文
  • SQL多级关系表示

    2010-05-07 12:38:00
    我们要建立多级关系,首先需要两个表. 第一个表表示直属结构,比如说我们公司...假如我们只有第一个表来表示关系的话。那么会很复杂。并且查询困难.所以需要两个表来表示他们之间的关系.或许你现在还没有认识到为什么

    我们要建立多级关系,首先需要两个表.
            第一个表表示直属结构,比如说我们公司有一个部门。而这个部门下还有3个小组,那么3个小组属于这个部门.第二个表表示多层结构,就象第一表里面所表示的,这三个小组同时还属于公司.而这个公司同时属于这3个小组的父级的父级的部门。假如我们只有第一个表来表示关系的话。那么会很复杂。并且查询困难.所以需要两个表来表示他们之间的关系.
    或许你现在还没有认识到为什么需要第二个表。
           那么现在我来给你说下。我现在有5个公司,并且每个公司下有5个部门。然后每个部门下有3个小组,而每个小组下有未知员工。然后我要查询其中一个公司的所有员工。那么你查询起来就很复杂了,首先你要查询出该公司下的所属部门,然后查询所属部门的所有小组,然后再查询所属小组的所有员工。这样才能查询到员工。
          但是,事情永远没有这么简单。比如说我有直属部门的员工。也就是说,他不属于小组,直接属于员工。那么你怎么办,只能union 或者用临时表。你可以说,我们可以把他们限制一下,员工不能属于部门,但是这是不合理的。甚至有可能他这个公司到小组结束了。另外一个公司却不止3层部门。那么你怎么办。不可能每个公司都搞个SQL语句吧。所以这时候就需要第二个表了。
         第二个表会表示出所有上级部门的关系,比如说:我有个公司,公司下面有个销售部,销售部下面有个销售一部,而销售一部下面有个销售一组.那么我们要查询这个销售一组的所有父级部门

    本部门       父级部门
    销售一组   销售一部
    销售一组   销售部
    销售一组   么么公司

    这样就很清楚了,因为我们只需要查
    select 父级部门 from tab where 本部门='销售一组'
    就全部出来了.而查询该公司下的所有部门则
    select 本部门 from tab where 父级部门='么么公司'
    该公司下的所有部门就出来了,然后我们只需要 inner join 一下,查询出部门的所有员工。很简单吧!
    我们现在思想说的差不多了,现在来说一下怎么具体实现。(我的目的是表示所有的多级关系,但是不包含历史记录的,比如说员工从A部门移动到b部门,我的里面都没有用事物处理,我是为了方便调用,比如移动员工吧,你首先update 下员工表,然后写入员工的历史记录。意思是员工在哪个部门下工作过)
    实现环境 :SQL 2005
    首先建立表:
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[Setting_Node](--直属表
    [intNodeId] [int] IDENTITY(1,1) NOT NULL,
    [intParNodeId] [int] NOT NULL,
    [intTableId] [int] NOT NULL,                --Setting_Table
    [strNode] [varchar](400) COLLATE Chinese_PRC_CI_AS NULL,
    [strMemo] [varchar](500) COLLATE Chinese_PRC_CI_AS NULL,
    [btIsDelete] [bit] NOT NULL CONSTRAINT [DF_Setting_Node_btIsDelete] DEFAULT ((0)),
    [intCreateOperaterId] [int] NOT NULL CONSTRAINT [DF_Table_1_intOperaterId] DEFAULT ((0)),
    [intUpdateOperaterId] [int] NOT NULL CONSTRAINT [DF_Setting_Node_intUpdateOperaterId] DEFAULT ((0)),
    [dtCreate] [datetime] NOT NULL CONSTRAINT [DF_Setting_Node_dtCreate] DEFAULT (getdate()),
    [dtUpdate] [datetime] NOT NULL CONSTRAINT [DF_Setting_Node_dtUpdate] DEFAULT (getdate()),
    CONSTRAINT [PK_Setting_Node] PRIMARY KEY CLUSTERED
    (
    [intNodeId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO
    SET ANSI_PADDING OFF

    /****** 对象: Table [dbo].[Setting_Layer]    脚本日期: 05/07/2010 12:14:08 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[Setting_Layer](--多层表示表
    [intLayerId] [int] IDENTITY(1,1) NOT NULL,
    [intNodeId] [int] NOT NULL,                     --Setting_Node
    [intParNodeId] [int] NOT NULL,                --Setting_Node
    [dtCreate] [datetime] NOT NULL CONSTRAINT [DF_Setting_Layer_dtCreate] DEFAULT (getdate()),
    [dtEnd] [datetime] NULL,
    [btIsDelete] [bit] NOT NULL CONSTRAINT [DF_Setting_Layer_btIsDelete] DEFAULT ((0)),
    CONSTRAINT [PK_Setting_Layer] PRIMARY KEY CLUSTERED
    (
    [intLayerId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    /****** 对象: Table [dbo].[Setting_Table]    脚本日期: 05/07/2010 12:15:03 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[Setting_Table]( --所属的表
    [intTableId] [int] IDENTITY(1,1) NOT NULL,
    [strTable] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,
    [strKey] [varchar](100) COLLATE Chinese_PRC_CI_AS NULL,
    [strMemo] [varchar](500) COLLATE Chinese_PRC_CI_AS NULL,
    CONSTRAINT [PK_Setting_Table] PRIMARY KEY CLUSTERED
    (
    [intTableId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO
    SET ANSI_PADDING OFF

    这三个表就是我们需要操作的表,一个是 Setting_Table ,因为我们可能表示多级关系,比如说员工表 (Setting_Operate) ,我们需要表示多级关系;另外还有其他表,比如说树等等.

    获取 Setting_Table的函数:
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go

    /* 获取表的ID,以便进行下一步操作 */
    Create FUNCTION [dbo].[fun_GetTableId]
    (
    @strKey varchar(100)='',
    @strTable varchar(200)=''
    )
    RETURNS int
    AS
    BEGIN
    DECLARE @Rt int

    IF @strKey<>''
    BEGIN
       SELECT @Rt =intTableId FROM dbo.Setting_Table WHERE strKey=@strKey
    END
    ELSE IF @strTable<>''
    BEGIN
       SELECT @Rt =intTableId FROM dbo.Setting_Table WHERE strTable=@strTable  
    END
    ELSE
    BEGIN
       SET @Rt=0
    END

    SET @Rt=ISNULL(@Rt,0)
      
    RETURN @Rt
    END

    插入一个结点的存储过程:
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go


    Create PROCEDURE [dbo].[proc_Setting_Node_Create]
        (
          @intParNodeId INT = 0 ,
          @intTableId INT = 0 ,
          @strNode VARCHAR(400) = '' ,
          @strMemo VARCHAR(500) = '' ,
          @intOperateId INT = 0
        )
    AS
        BEGIN
            SET NOCOUNT ON ;
            DECLARE @Rt INT
            INSERT INTO dbo.Setting_Node
                    ( intParNodeId ,
                      intTableId ,
                      strNode ,
                      strMemo ,
                      btIsDelete ,
                      intCreateOperaterId ,
                      intUpdateOperaterId ,
                      dtCreate ,
                      dtUpdate
               )
            VALUES ( @intParNodeId , -- intParNodeId - int
                      @intTableId , -- intTableId - int
                      @strNode , -- strNode - varchar(400)
                      @strMemo , -- strMemo - varchar(500)
                      0 , -- btIsDelete - bit
                      @intOperateId , -- intCreateOperaterId - int
                      @intOperateId , -- intUpdateOperaterId - int
                      GETDATE() , -- dtCreate - datetime
                      GETDATE() -- dtUpdate - datetime
               )
            
            SET @Rt = SCOPE_IDENTITY()

            DECLARE @parId INT
            SET @parId = @intParNodeId
            WHILE @parId <> 0
                BEGIN
                    INSERT INTO dbo.Setting_Layer
                            ( intNodeId ,
                              intParNodeId ,
                              dtCreate ,
                              dtEnd ,
                              btIsDelete
                  )
                    VALUES ( @Rt , -- intNodeId - int
                              @parId , -- intParNodeId - int
                              GETDATE() , -- dtCreate - datetime
                              NULL , -- dtEnd - datetime
                              0 -- btIsDelete - bit
                  )
                    SELECT @parId = intParNodeId
                    FROM dbo.Setting_Node
                    WHERE   intNodeId = @parId
                END
             RETURN @Rt
        END


    插入的调用方法:
    条件数据:
    Setting_Table数据

    1 Setting_Operater Setting_Operater 操作员

    插入执行:
    DECLARE @intTableId INT
    DECLARE @intParId INT
    EXEC @intTableId=dbo.fun_GetTableId
    @strKey = 'Setting_Operater', -- varchar(100)
        @strTable = 'Setting_Operater' -- varchar(200)
    --SELECT @intTableId

    DECLARE @intTotalId INT

    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = 0, -- int
        @intTableId = @intTableId, -- int
        @strNode = '么么公司', -- varchar(400)
        @strMemo = '么么公司', -- varchar(500)
        @intOperateId = 0 -- int
       
    SET @intTotalId=@intParId

    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intTotalId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '销售部', -- varchar(400)
        @strMemo = '销售部', -- varchar(500)
        @intOperateId = 0 -- int
    /*-----------------------------------------------------------------------*/
    DECLARE @intSaleDeptId INT
    SET @intSaleDeptId=@intParId
    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intSaleDeptId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '销售一部', -- varchar(400)
        @strMemo = '销售一部', -- varchar(500)
        @intOperateId = 0 -- int

    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intSaleDeptId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '销售二部', -- varchar(400)
        @strMemo = '销售二部', -- varchar(500)
        @intOperateId = 0 -- int
       
    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intSaleDeptId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '销售三部', -- varchar(400)
        @strMemo = '销售三部', -- varchar(500)
        @intOperateId = 0 -- int
       
    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intSaleDeptId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '销售四部', -- varchar(400)
        @strMemo = '销售四部', -- varchar(500)
        @intOperateId = 0 -- int

    /*-----------------------------------------------------------------------*/
    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intTotalId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '财务部', -- varchar(400)
        @strMemo = '财务部', -- varchar(500)
        @intOperateId = 0 -- int

    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intTotalId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '仓库部', -- varchar(400)
        @strMemo = '仓库部', -- varchar(500)
        @intOperateId = 0 -- int

    EXEC @intParId=dbo.proc_Setting_Node_Create
    @intParNodeId = @intTotalId, -- int
        @intTableId = @intTableId, -- int
        @strNode = '物流部', -- varchar(400)
        @strMemo = '物流部', -- varchar(500)
        @intOperateId = 0 -- int

    SELECT * FROM dbo.Setting_Layer

    SELECT * FROM dbo.Setting_Node

    --TRUNCATE TABLE dbo.Setting_Node
    --TRUNCATE TABLE dbo.Setting_Layer

    SELECT a.intNodeId ,
            a.strNode ,
            c.intNodeId ,
            c.strNode
    FROM    dbo.Setting_Node AS a
            INNER JOIN dbo.Setting_Layer AS b ON a.intNodeId = b.intNodeId
            INNER JOIN dbo.Setting_Node AS c ON b.intParNodeId = c.intNodeId
    好了,我们就搞到这里,相信删除和修改已经很容易了。大家能够搞定,两个表能够解决很多问题。第一,查询效率的提升。第二,结构的清楚理解

    展开全文
  • 在这节课中,你需要复习每一个关键字,从记忆中想起它的作用并且写下来,接着上网搜索它真正的功能。有些内容可能是无法搜索的,所以这对你可能有些难度,不过你还是需要坚持尝试。如果你发现记忆中的内容有误,就在...

    现在该复习你学过的符号和 python 关键字了,而且你在本节还会学到一些新的东西。我在这里所作的是将所有的 Python 符号和关键字列出来,这些都是值得掌握的重点。

    在这节课中,你需要复习每一个关键字,从记忆中想起它的作用并且写下来,接着上网搜索它真正的功能。有些内容可能是无法搜索的,所以这对你可能有些难度,不过你还是需要坚持尝试。

    如果你发现记忆中的内容有误,就在索引卡片上写下正确的定义,试着将自己的记忆纠正过来。如果你就是不知道它的定义,就把它也直接写下来,以后再做研究。

    最后,将每一种符号和关键字用在程序里,你可以用一个小程序来做,也可以尽量多谢一些程序来巩固记忆。这里的关键点是明白各个符号的作用,确认自己没搞错,如果搞错了就纠正过来,然后将其用在程序里,并且通过这样的方式巩固自己的记忆。

    Keywords (关 键 字)

    1 andif a=b and c=d:

    1 del    用于list列表操作,删除一个或者连续几个元素。list = [1,2,3,4]

    del list[1]

    print list

    def    创建函数def word():

    print"不错"

    return    返回值def maximun(x, y):

    if x > y:

    return x

    elif x 

    return y

    print maximun(2,3)

    � from    导入模块,导入模块指定命令,尽量少用这种方法from sys import argv

    � import    导入模块,导入整个模块import sys

    � not    逻辑判断词,用于布尔型True和False,not True为False,not False为Truea = False

    if  not a:

    print a

    or

    # -*- coding:utf-8 -*-

    a = [1,2,3]

    b = 5

    if b not in a:

    print"b的值不在a中"

    � for    for循环for i in range(0,6):

    print i

    � while    while循环while True:

    print"你是好人"

    � continue    继续循环for i in range(0,10):

    if i ==5:

    continue

    print

    � break    结束循环x = 2

    while True:

    x + = 1

    print x

    if x > 5:

    break

    � asimport sys as sys1

    � global    将变量定义为全局变量。可以通过定义为全局变量,实现在函数内部改变变量值。

    一个global语句可以同时定义多个变量,如 global x, y, zdef func():

    global x

    print 'x is', x

    x = 2

    print 'Changed local x to', x

    x = 50

    func()

    print 'Value of x is', x

    � or    或者if x>y or y

    print"不错"

    � with

    � assert

    � ifif x>y:

    print"你是好人"

    elif x

    print"他是好人"

    else:

    rint"都不是好人"

    � elifif x>y:

    print"你是好人"

    elif x

    print"他是好人"

    else:

    rint"都不是好人"

    � elseif x>y:

    print"你是好人"

    elif x

    print"他是好人"

    else:

    rint"都不是好人"

    � pass

    是空语句,是为了保持程序结构的完整性。

    pass 不做任何事情,一般用做占位语句。for letter in 'Python':

    if letter == 'h':

    pass

    print '这是 pass 块'

    print '当前字母 :', letter

    print "Good bye!"

    结果:当前字母 : P

    当前字母 : y

    当前字母 : t

    这是 pass 块

    当前字母 : h

    当前字母 : o

    当前字母 : n

    Good bye!

    � yield

    � except

    � print    输出print"前面有好东西"

    � class

    � exec

    � infor i in range(0,6):

    print i

    � raise

    � finally

    � is

    � lambda 匿名函数,即,函数没有具体的名称。bar = lambda:'beginman'

    print bar()    #结果:beginman

    � try

    数据类型

    针对每一种数据类型,都举出一些例子来,例如针对 string ,你可以举出一些字符串,针对 number ,你可以举出一些数字。

    � True

    � False

    � None

    � strings

    � numbers

    � floats

    � lists

    字符串转义序列(Escape Sequences)

    对于字符串转义序列,你需要再字符串中应用它们,确认自己清楚地知道它们的功能。

    � \\    \

    � \'    '

    � \"    "

    � \a    响铃

    � \b    退格(Backspace)

    � \f    换页

    �     空行

    � \r    回车

    � \t    横向制表符,相当于tab  ,6个空格

    � \v    纵向制表符

    字符串格式化(String Formats)

    一样的,在字符串中使用它们,确认它们的功能。

    � %d    带符号的十进制整数

    � %i     带符号的十进制整数

    � %o    不带符号的八进制

    � %u    不带符号的十进制

    � %x    不带符号的十六进制(小写)

    � %X    不带符号的十六进制(大写)

    � %e    科学计数法表示的浮点数(小写)

    � %E    科学计数法表示的浮点数(大写)

    � %f    十进制浮点数

    � %F    十进制浮点数

    � %g    如果指数大于-4或者小于精度值和e相同,其他情况与f相同

    � %G    如果指数大于-4或者小于精度值和E相同,其他情况与F相同

    � %c    单字符(接受证书或者单字符字符串)

    � %r    字符串(使用repr转换任意Python对象)

    � %s    字符串(使用str转换任意Python对象)

    � %%    输出单一%

    操作符号

    有些操作符号你可能还不熟悉,不过还是一一看过去,研究一下它们的功能,如果你研究不出来也没关系,记录下来日后解决。

    � +    加

    � -    减

    � *    乘

    � **    乘方    如2**4,结果就是2的4次方,结果是16

    � /    除

    � //    用于浮点数除法,其结果进行四舍五入。如在python2.7中,print 2/3 结果为0

    � %    取余

    � >    大于

    � <=    小于等于

    � >=    大于等于

    � ==    等于

    � !=    不等于

    � <>    不等于    比较少用

    � ( )     元组

    � [ ]    列表

    � { }    字典

    � @

    � ,

    � :

    � .

    � =    赋值

    � ;

    � +=    加法赋值运算符如x += 1 等于 x = x + 1

    � -=    减法赋值运算符

    � *=    乘法赋值运算符

    � /=    除法赋值运算符

    � //=    取整除赋值运算符

    � %=    去模赋值运算符

    � **=    幂赋值运算符

    花一个星期学习这些东西,如果你能提前完成就更好了。我们的目的是覆盖到所有的符号类型,确认你

    已经牢牢记住它们。另外很重要的一点是这样你可以找出自己还不知道哪些东西,为自己日后学习找到

    一些方向。

    阅读代码

    现在去找一些 Python 代码阅读一下。你需要自己找代码,然后从中学习一些东西。你学到的东西已经足够让你看懂一些代码了,但你可能还无法理解这些代码的功能。这节课我要教给你的是:如何运用你学到的东西理解别人的代码。

    首先把你想要理解的代码打印到纸上。没错,你需要打印出来,因为和屏幕输出相比,你的眼睛和大脑更习惯于接受纸质打印的内容。一次最多打印几页就可以了。

    然后通读你打印出来的代码并做好标记,标记的内容包括以下几个方面:

    1. 函数以及函数的功能。

    2. 每个变量的初始赋值。

    3. 每个在程序的各个部分中多次出现的变量。它们以后可能会给你带来麻烦。

    . 任何不包含 else 的 if 语句。它们是正确的吗?

    5. 任何可能没有结束点的 while 循环。

    6. 最后一条,代码中任何你看不懂的部分都记下来。

    接下来你需要通过注解的方式向自己解释代码的含义。解释各个函数的使用方法,各个变量的用途,以及任何其它方面的内容,只要能帮助你理解代码即可。

    最后,在代码中比较难的各个部分,逐行或者逐个函数跟踪变量值。你可以再打印一份出来,在空白处写出你要“追踪”的每个变量的值。

    一旦你基本理解了代码的功能,回到电脑面前,在屏幕上重读一次,看看能不能找到新的问题点。然后继续找新的代码,用上述的方法去阅读理解,直到你不再需要纸质打印为止。

    加分习题

    1. 研究一下什么是“流程图 (flow chart)” ,并学着画一下。

    2. 如果你在读代码的时候找出了错误,试着把它们改对,并把修改内容发给作者。

    3. 不使用纸质打印时,你可以使用注解符号 # 在程序中加入笔记。有时这些笔记会对后来的读代码的人有很大的帮助。

    常见问题回答

    %d 和 %i 有何不同?

    没有什么不同,只不过由于历史原因,用 %d 的人更多一些而已。

    怎样在网上搜索这些东西?

    在你要搜索的东西前面加上“ python” 就可以了,比如说你要搜索 yield ,就输入python yield

    展开全文
  • IPFS和Filecoin是什么关系 ? Filecoin和IPFS同属于《协议实验室》旗下的明星项目,都是用于在分布式Web中存储和共享数据的基础协议。V Awdbank 两种系统都是免费的,开源的,并且共享许多构件,包括数据表示格式...

    IPFS和Filecoin是什么关系 ?


    在这里插入图片描述

    Filecoin和IPFS同属于《协议实验室》旗下的明星项目,都是用于在分布式Web中存储和共享数据的基础协议。V Awdbank

    两种系统都是免费的,开源的,并且共享许多构件,包括数据表示格式(IPLD)和网络通信协议(libp2p)。
    在这里插入图片描述
    尽管不需要使用Filecoin与IPFS进行交互,但是所有Filecoin节点都是幕后的IPFS节点,并且可以使用libp2p连接到其他IPFS节点并从中获取IPLD格式的数据。

    但是,Filecoin节点不加入或参与公共IPFS DHT。

    数据存储激励
    IPFS允许用户在对等网络中存储和传输可验证的,内容寻址的数据。IPFS用户将所需的数据保留在自己的IPFS节点上,这称为固定。有时,可以使用第三方固定服务或通过单个IPFS用户组来固定数据。

    只要一个用户存储数据并能够在其他用户请求时将其提供给其他用户,数据就存在于网络中。
    在这里插入图片描述
    IPFS没有内置机制来激励数据存储,而Filecoin作为IPFS的激励层,希望通过区块链激励人们提供分布式存储空间。

    Filecoin网络创建了用于长期存储的分布式存储市场,具有大存储容量的节点可以将存储空间租给存储用户。

    Filecoin网络可确保安全存储数据,但是,存储(密封),验证(证明)和开封(用于检索)的过程在计算上是昂贵的,并且会花费很长时间。

    因此,Filecoin开启了一个额外的检索市场,在该市场中,专用节点可以通过保留未密封的缓存副本来帮助快速从网络交付内容以进行支付,该传递机制可以利用IPFS进行。

    Filecoin可以看作是一个冷存储层,是安全存储大量数据的理想选择。IPFS将是热存储层,旨在快速检索和分发内容。

    用户应该选择使用哪个系统?
    在这里插入图片描述
    使用IPFS

    由用户自己的节点自己存储数据,否则,必须依靠其他对等方来自愿/自动存储数据或使用集中式固定服务。
    必须信任集中式IPFS固定服务才能完成其工作,IPFS没有内置的规定来验证固定服务是否存储了数据并正确提供了数据。
    IPFS本身非常适合流行的内容(与许多提供商一起使用),激励在多个节点上同步和存储数据的组织以及可以使用强大的社会契约来确保内容长期保存和维护的组织。
    使用Filecoin
    客户与矿工进行存储交易以存储数据,网络验证矿工是否正确存储了数据,在仓储交易期间定期支付存储费用。
    不遵守存储协议的矿工将受到处罚。
    内容检索可以由存储矿工直接提供,也可以由专门的检索矿工提供。请求数据的用户为此服务付费。
    Filecoin擅长长时间存储大量数据。
    两者同时使用
    一些解决方案结合了两个系统中的最佳功能,在Filecoin网络上备份数据,同时通过IPFS网络提供数据快速访问。V Awdbank

    这样可以确保数据始终可用并且可以快速检索,同时还可以确保将数据安全地备份到Filecoin网络上。

    Powergate是基于Filecoin和IPFS构建的多层文件存储API,并且是Filecoin数据的索引生成器。

    在这里插入图片描述
    IPFS和Filecoin背后的技术

    Filecoin和IPFS在许多层面上都采用了相同的技术:

    知识产权联盟指定内容寻址数据的数据格式,例如区块链或IPFS存储文件的方式。
    libp2p提供对等网络功能,连接安全性以及密钥发现和数据分发功能,例如DHT和Pubsub。
    多种格式定义面向未来的标识符和数据类型。
    图同步和Bitswap支持在节点之间快速高效地进行IPLD数据传输。
    在这里插入图片描述
    可以看到同样作为协议实验室的明星项目,IPFS作为前沿的去中心化存储网络底层协议,目前已经被包括华为、京东、广电等进行研究和应用。V Awdbank

    目前运行在IPFS公网上的应用已经有几百个,并且很多传统的大互联网公司都基于IPFS进行存储。

    在这里插入图片描述
    而Filecoin经过3年多的研发长跑,主网也已经于2020年10月15日正式上线了。

    作为分布式存储赛道无可争议的龙头项目,随着Filecoin主网上线平稳运行,未来基于Filecoin和IPFS网络的应用和生态会逐步建立,Filecoin的长期价值会逐步显现。

    展开全文
  • JSP 和Servlet 有有什么关系? Servlet是一个特殊的Java程序,它运行于服务器的JVM中,能够依靠服务器的支持向浏览器提供显示内容。 JSP本质上是Servlet的一种简易形式, JSP会被服务器处理成一个类似于Servlet的...
  • 两种系统都是免费的,开源的,并且共享许多构件,包括数据表示格式(IPLD)和网络通信协议(libp2p)。 尽管不需要使用Filecoin与IPFS进行交互,但是所有Filecoin节点都是幕后的IPFS节点,并且可以使用libp2p...
  • 关系数据库是什么? 由数据表和数据表之间的关联组成 关系数据库的特点 每个具有相同属性的数据独立地存在一个表中,用户可以对表中的数据进行新增、删除和修改,并且不会影响表中其他的数据 基本术语 键码...
  • 每个连接到Internet上的主机都会分配一个IP地址,是用来唯一表示互联网上计算机的逻辑地址,机器之间的访问就是通过IP地址来访问的。 域名:是一串用点分隔的名字组成的Internet上某一台计算机或计算机的名称,用于...
  • 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。通常用两个字节表示一个字符,原有的英文编码从单字节变成...
  • 什么使用列向量表示一条数据:使用列向量使得在之后的矩阵相乘时更加方便,并且符合数学公式的表达方式,比如第6条中 Y = HX,其表示将X表示的数据降维到k维,即将X投影到H表示的空间中,线性代数中一般均采用左侧...
  • 我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。大部分留言,我都在相对应...
  • 根据使用的软件包,依赖关系可以通过将任务及其后续任务的标识符进行关联来表示。依赖关系说明了任务之间关联/并列的要求。依赖关系可以是指在另一个任务能开始之前有一个任务必须完成。例如,逻辑模型必须在物理...
  • Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。 因为计算机只能处理数字,如果要处理文本,就...
  • 算法:是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。 我们在学习数据结构或者谈论到数据结构的时候总是会跟算法扯在一起,就连我的专栏分类名字都叫做 数据结构...
  • 设计类图是类图的一个变体,类图表示一系列的类以及它们之间的关系。因为分析阶段是一个发现需求的过程,所以我们一般很少关心类的属性和方法的细节。在面向对象设计中,类的属性有一个特征叫可见性,它表示其它类...
  • 什么是nosql NoSQL是用于指代与传统关系数据库管理系统(RDBMS)在许多方面不同的一类数据库系统的术语。 使用SQL访问RDBMS。 因此,术语NoSQL表示不被SQL访问。 更具体地说,不是RDBMS,或者更准确地说,是非关系...
  • 卡尔·古斯塔夫·荣格(Carl Gustav Jung)的同步性概念表示,如果事件在没有因果关系的情况下发生,但似乎有意义地关联,则它们是“有意义的巧合”。 最近发生在我身上的这件事与一些请求有关。 我正在处理一个FOSS...
  • 卡尔·古斯塔夫·荣格(Carl Gustav Jung)的同步性概念表示,如果事件在没有因果关系的情况下发生,但似乎有意义地关联,则它们是“有意义的巧合”。 最近发生在我身上的这件事与一些请求有关。 我正在处理一个...
  • 什么是模块,什么是组件

    千次阅读 2018-08-15 19:53:55
    相同:都是基于功能划分的单位。比如说完成网络功能的组件、模块、完成统计功能的组件、模块;...比如“XXX采集卡通用远程监控组件”,表示这个东东是完成远程监控功能,并且是为了可重用而开发的. 这个组件本身由采...
  • 说干就干,马上海选女主角(和老谋子学的,此举可以吸引媒体的眼球,呵呵),并且特别规定,演员必须具有ac的基本功,否则直接out! 由于策划师风之鱼(大师级水王)宣传到位,来应聘的MM很多,当然包括nit的蛋糕...
  • 什么是NoSQL?

    2020-04-14 16:38:05
    因此,术语NoSQL表示不被SQL访问。 更具体地说,不是RDBMS,或者更准确地说,是非关系的。 NqSQL数据库的一些关键特征是: 它们是分布式的,可以水平扩展,并且可以处理数个TB或PB数量级的数据量,而延迟时间很...
  • 一、什么是比例尺?比例尺是表示图上距离比实地距离缩小的程度,因此也叫缩尺。用公式表示为:比例尺=图上距离/实地距离。例如地图上1厘米代表实地距离500千米,可写成:1∶50,000,000或写成:1/50,000,000。在当前...
  • 组合和继承有什么区别?

    千次阅读 2018-10-23 14:56:43
    可以使用现有类的功能,并且在无需重复编写原有类的情况下对原有类进行功能上的扩展。(is-a关系) 3.实例比较 Vehicle表示交通工具对象 Car表示汽车对象 Tire表示轮胎对象 /** *继承 */ class Vehicle{ } class ...
  •   AQS(AbstractQueuedSynchronizer)是JAVA中众多锁以及并发工具的基础,其底层采用乐观锁,大量使用了CAS操作, 并且在冲突时,采用自旋方式重试,以实现轻量级和高效地获取锁。   提供一个框架,用于实现...
  • 什么是文本?

    千次阅读 2019-04-17 23:16:16
    计算机只能理解数字,并且所有的数据都将转换成数值来表示。 文本是一种字符与数字之间简单的一对一映射,它非常紧凑,由50个字符构成的文本在转换为数据时候也是50个字符。 区别:压缩后的视频文件、doc文档(含有...
  • 地图分辨率和zoomlevel之间的关系) 一、什么是比例尺? 比例尺是表示图上距离比实地距离缩小的程度,因此也叫缩尺。用公式表示为:比例尺=图上距离/实地距离。 例如地图上1厘米代表实地距离500千米,可写成...
  • 什么是约束? 为了确保表中数据的完整性(即准确性、正确性),为表添加的一些限制。是数据库中表设计最基本的一个规则。使用约束可以使数据操作更加精准,并且减少冗余数据(脏数据)。 (一)主键约束 主键 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 381
精华内容 152
关键字:

并且表示什么关系