精华内容
下载资源
问答
  • 如果将块下载到 CPU 时该 CPU 上已存在相同名称的块,则会发生名称冲突。 必须手动更正“相互矛盾的更改”。两名编辑人员同时在两套工程组态系统上使用相同的块时将出现相互矛盾的更改。第一名编辑人员仍可以将其...

    作为 Team Engineering 的一部分,用户可以选择执行项目共享调试。在此期间,多个编辑人员可以通过最多5套工程组态系统 (ES) 同时访问一个 CPU。

    其优势在于,在调试期间可同时对主项目的一部分进行单独编辑和离线编辑。可能的话,在装载期间其他编辑人员所做的更改将显示在“软件同步”(Software synchronization) 对话框中并自动同步。

    3500cdd6698f624ecc0184fa0622c473.png

    根据所用 CPU 的固件版本,某些在线功能也可以同时从共享 CPU 上的多个工程组态系统执行,如:

    • 监视 CPU 上的块
    • 监视并强制 CPU 上的块
    • 跟踪功能

    以下在线功能无法同时执行:

    • 加载:只有一个工程组态系统可以装载到 CPU 中。

    一、共享调试的规则

    如果作为团队项目的一部分对项目进行共享调试,则该项目的所有编辑人员都必须遵循既定的规则进行操作,以确保合作成功。

    主项目的规则

    必须遵循以下规则:

    • 创建适合共享编辑的主项目。
    • 将用户程序分成多个相互独立的部分。
    • 使用“组”将程序部分之间相互分开。
    • 针对调用部分程序函数的每个程序部分,使用一个主 OB 和一个中央 FC。
    • 尽量为每个部分创建一个单独的 PLC 变量表。
    • 在主项目中,指定无法在项目副本中更改的项目语言。
    • 如果要在程序部分之间交换数据,请使用 FC 和 FB 接口参数(IN、OUT、INOUT)或全局数据块。
    • 使用全局数据块保存各个程序部分的数据,不使用位存储器。
    • 对于具有相同地址的块,不要为其指定不同的名称。
    • 对于具有不同地址的块,不要为其指定相同的名称。

    主项目中程序结构的示例

    该示例是一个支持团队的结构化主项目,适合在共享调试期间并行编辑。

    各工程组态系统可编辑的程序段,如下所示:

    • 程序第 1 部分:“Conveyer”
    • 程序第 2 部分:“Drill”
    • 程序第 3 部分:“FurtherProgramPart”

    每个程序部分包含一个“主FB”,它调用此程序部分的特定低级函数。

    示例:在程序段“Conveyer”中,“ConveyerMainFB”将调数“ConveyerStartupFC”。

    348a5f9d4cc538ae585464f2c7c41c85.png

    在团队项目中,项目结构的这种细分允许并行编辑各个程序部分,并允许在共享调试阶段自动同步所做的更改。

    共享 CPU 的规则

    请遵守以下共享工作规则:

    • 编辑人员仅在分配的组中编辑项目副本中分配到的块。
    • 在项目副本中只能更改 OB、FB、DB、FC 和 UDT。即,项目副本中的以下程序元素无法编辑:
    • 硬件配置
    • PLC 变量表
    • 工艺对象
    • 文本列表和项目语言
    • F 块
    • 应在编程中使用全局数据块,而非位存储器。
    • 应在编程中使用 IEC 定时器和计数器,而非 SIMATIC 定时器和计数器。
    • 在主项目中指定的项目语言无法在项目副本中更改。

    编辑共享中央对象的规则

    请遵守以下共享中央对象规则:

    • 对共享中央对象的更改始终需要通过主项目进行。
    • 这些对象包括:
    • 硬件配置
    • PLC 变量表
    • 工艺对象
    • 文本列表和项目语言
    • F 块
    • 项目副本中的各种工作版本需要首先再次集成到主项目中,然后才能在主项目中修改共享中央对象。
    • 随后可以在主项目中进行修改,并可以将主项目下载到共享 CPU。
    • 修改完成后,可以创建新项目副本并分配到工程组态系统以进一步处理。

    组织块的使用规则

    编辑 OB 时,请遵守以下规则:

    • OB 只能在模板副本中创建。如果新的 OB 在项目副本中创建,则无法进行同步。
    • OB 包含在主项目中且已下载到 CPU 中时,在相应的项目副本中可对这些 OB 进行修改。在下载过程中,这些组织块将自动进行同步。

    下载到 CPU 的规则

    请遵守以下下载规则:

    • 编辑人员仅可相继下载项目副本到 CPU;任何时候仅有一个工程组态系统可以下载。
    • 下载块时(硬件只能下载到主项目中),可保持参与工程组态系统的在线连接。
    • 下载时在同步对话框中执行自动同步。这样可以确保其他编辑人员的更改不会被意外覆盖。
    • 更正同步对话框中显示的名称冲突,下载到 CPU 之前,在离线块中对其进行重命名。如果将块下载到 CPU 时该 CPU 上已存在相同名称的块,则会发生名称冲突。
    • 必须手动更正“相互矛盾的更改”。两名编辑人员同时在两套工程组态系统上使用相同的块时将出现相互矛盾的更改。第一名编辑人员仍可以将其更改下载到 CPU,而不会出现任何问题。但如果第二名编辑人员想下载同一个已被更改过的块,则同步对话框将显示有冲突且无法自动解决。之前对该块进行的更改会在下载期间因覆盖而被撤销。在这种情况下,编辑人员需要决定应用和放弃哪个更改。或者也可以通过在比较编辑器中对块进行详细对比,手动合并这些更改。
    • 通过规划好项目结构,并在编辑人员之间达成相应的一致意见,就可以避免这种相互矛盾的更改。
    • 对中央对象的更改显示在同步对话框中,但是无法自动同步。对中央对象和硬件配置的更改始终需要通过主项目进行。
    • 在每次下载后保存项目或项目副本。

    说明在项目副本中创建对象并将其随后删除

    请注意,在项目副本中创建新对象并将其随后立即删除时,在下载之前也需要进行软件同步。

    创建对象会导致内部数据管理发生更改,而随后删除该对象并无法撤消这种更改。因此如果新创建的对象随后被立即删除,那么在下一次装载前就必须进行同步,在项目副本的现有对象中将看不到任何更改。

    在线功能的规则

    使用在线功能时必须遵循以下规则:

    加载:

    • 无论何时,只能一个工程组态系统将数据下载到 CPU 中。
    • 在下载过程中,其它工程组态系统可使用其它在线功能,如监视与控制。

    监视和控制:

    • 在 CPU 块上最多可以同时监视和控制五个工程组态系统。
    • 一个特定的代码块只能同时被一个工程组态系统监视和控制。
    • 但其它工程组态系统可以同时监视和控制其它代码块。

    注意 使用多个监控表中的不同修改值并行修改相同操作数时存在风险

    处理多个监控表时,请避免使用不同修改值永久多次修改相同操作数。

    如果同时使用不同监控表中的不同修改值来永久修改相同操作数,所有监控表将显示最新修改值,因为在这种情况下将使用分配的最新修改值。

    强制

    • 一次只能在一个工程组态系统中的 CPU 上进行强制。
    • 启动强制功能的工程组态系统独占地接管强制作业。尽管其它工程组态系统能够收到强制作业正在运行的信息,但它们却无法访问此作业进行更改。使用“更新强制操作数”(Update forced operands) 命令,将更新已打开的强制表中当前在 CPU 上强制的所有操作数和值。使用相关值更新已打开的强制表中的所有强制操作数。一个红色“F”显示在第一列中,表示强制的操作数。
    • 在强制作业所属的工程组态系统结束了在线连接后,此强制作业可由另一个与 CPU 建立了在线连接,并执行“更新强制操作数”(Update forced operands) 命令。这会启用“全部强制”(Force all) 和“停止强制”(Stop forcing) 按钮,您可以选择这些功能。

    跟踪功能:

    • 最多四个工程组态系统可同时执行跟踪功能。
    • 启动跟踪功能的工程组态系统独占地接管跟踪作业。尽管其它工程组态系统可以在跟踪编辑器中看到此作业,但却无法访问此作业。
    • 在跟踪作业所属的工程组态系统关闭了跟踪编辑器后,此跟踪作业可由另一个重新打开跟踪编辑器的工程组态系统接管。

    二、共享调试的步骤

    创建主项目的步骤

    可以通过以下步骤创建主项目:

    1. 创建包含整个项目结构的主项目。
    2. 针对主项目全面配置硬件。
    3. 定义一种语言作为项目语言,该语言还必须被所有参与的工程组态系统独占使用。
    4. 创建主项目中需要的所有变量和块。
    5. 为将要由各个工程组态系统编辑的块创建自己的文件夹和组。
    6. 创建完全设定且可执行的用户程序。
    7. 将主项目下载到共享 CPU 中。
    8. 在每次下载后保存主项目。

    共享调试的步骤

    共享调试按照以下步骤进行:

    1. 将主项目下载到共享 CPU 中。
    2. 在相关工程组态系统上创建主项目的副本,并将其分配给参与项目的编辑人员。
    3. 通知将要编辑项目副本指定部分且可能下载到 CPU 的所有编辑人员。
    4. 在各个工程组态系统中编辑项目副本。
    5. 编辑后,各个工程组态系统会将所做的更改相继下载到 CPU 中。
    6. 所有改动都会在装载期间通过在线-离线比较自动检测到。显示的同步对话框可提供已修改数据的同步建议。首先需要将其他编辑人员编辑的块下载到您的工程组态系统中,然后才能将您的更改下载到 CPU 中。更新已下载到项目副本 CPU 中的其他编辑人员的修正时可能需要这么做。提供以下同步选项:
    • 下载块:CPU 上已编辑过的块,必须在您的项目副本中更新。
    • 下载块:CPU 上的新块,必须下载到您的项目副本中。
    • 具有相互矛盾的更改的块:在这种情况下无法进行系统支持的同步;必须手动解决冲突。

    7.手动解决可能因相互矛盾的更改或对中央对象的更改而出现的任何冲突。

    8.在解决了所有冲突之后,将项目副本下载到 CPU。

    9.在每次下载后保存项目副本。

    10.重复编辑项目副本并根据需要多次下载到 CPU,直到完成共享调试。

    11.再次将完全编辑过的项目副本集成到主项目中,同时也备份仅离线存在的项目数据。

    手动同步相互矛盾的更改的步骤

    可以通过以下步骤手动同步相互矛盾的更改:

    1. 启动比较编辑器,手动解决下载到 CPU 时显示在同步对话框中的冲突。在项目树中选择共享 CPU,然后在快捷菜单中选择“比较 > 离线/在线”(Compare > Offline/Online) 命令。可以根据对象的状态确定所需执行的操作。但是,请注意同步期间只能执行单方向的操作。
    2. 首先对其它编辑人员在 CPU 上更改的所有块以及用户希望应用的所有块选择“从设备上传”(Upload from device) 操作。
    3. 如有必要,对块进行详细的对比以了解 CUP 上装载的离线块与在线块的区别。
    4. 手动更正块的相互矛盾的更改。
    5. 然后使用“继续而无需同步”(Continue without synchronization) 命令将受影响的块下载到 CPU。
    6. 在每次下载后保存项目或项目副本。

    将项目副本集成到主项目中的步骤

    通过以下步骤将项目副本集成到主项目中:

    1. 打开主项目和将作为参考对象集成的项目副本。
    2. 将编辑过的程序部分从对应的项目副本复制到主项目,并确认覆盖了现有对象。还可以使用比较编辑器将程序部分应用到主项目。
    3. 保存主项目,并使用“继续而无需同步”(Continue without synchronization) 命令将其下载到共享 CPU。
    4. 在每次下载后保存主项目。

    修改主项目中中央对象的步骤

    通过以下步骤,修改对所有程序部分都有影响的中央对象:

    1. 停止对项目副本的进一步处理。
    2. 如上文所述,将现有的所有项目副本都相继集成到主项目中。
    3. 使用“继续而无需同步”(Continue without synchronization) 命令将主项目下载到共享 CPU。
    4. 在共享对象上进行所需的修改,如硬件配置或 PLC 变量表。同理,修改工艺对象、F 块、OB 等其它中央对象。
    5. 修改完成后,再次将主项目下载到 CPU 中。
    6. 在每次下载后保存主项目。
    7. 将更新过的项目副本分配到对应的工程组态系统中,以进一步处理。
    展开全文
  • 锁定力度小,发生冲突概率低,可以实现的并发度高,但是对于锁的开销比较大,加锁会比较慢,容易出现死锁情况。页锁就是在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有...

    索引和锁是数据库中的两个核心知识点,隔离级别的实现都是通过锁来完成的

    按照锁颗粒对锁进行划分 ?

    锁用来对数据进行锁定,我们可以从锁定对象的粒度大小来对锁进行划分,分别为行锁、页锁和表锁。

    • 行锁就是按照行的粒度对数据进行锁定。锁定力度小,发生锁冲突概率低,可以实现的并发度高,但是对于锁的开销比较大,加锁会比较慢,容易出现死锁情况。
    • 页锁就是在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行。页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。
    • 表锁就是对数据表进行锁定,锁定粒度很大,同时发生锁冲突的概率也会较高,数据访问的并发度低。不过好处在于对锁的使用开销小,加锁会很快。

    还有区锁和数据库锁.

    182ffe395e967f79a97d577c4335dee1.png

    每个层级的锁数量是有限制的,因为锁会占用内存空间,锁空间的大小是有限的。当某个层级的锁数量超过了这个层级的阈值时,就会进行锁升级。锁升级就是用更大粒度的锁替代多个更小粒度的锁,比如 InnoDB 中行锁升级为表锁,这样做的好处是占用的锁空间降低了,但同时数据的并发度也下降了。

    从数据库管理的角度对锁进行划分

    共享锁和排它锁

    • 共享锁也叫读锁或 S 锁,共享锁锁定的资源可以被其他用户读取,但不能修改。在进行SELECT的时候,会将对象进行共享锁锁定,当数据读取完毕之后,就会释放共享锁,这样就可以保证数据在读取时不被修改。
    38d88b7ab03150777ea29c5debf5f9f6.png
    • 排它锁也叫独占锁、写锁或 X 锁。排它锁锁定的数据只允许进行锁定操作的事务使用,其他事务无法对已锁定的数据进行查询或修改。
    0a97a06812a14dc87d874518caf04ca2.png

    当我们对数据进行更新的时候,也就是INSERT、DELETE或者UPDATE的时候,数据库也会自动使用排它锁,防止其他事务对该数据行进行操作。

    意向锁(Intent Lock),简单来说就是给更大一级别的空间示意里面是否已经上过锁。

    从程序员的角度对锁进行划分

    乐观锁

    乐观锁(Optimistic Locking)认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,也就是不采用数据库自身的锁机制,而是通过程序来实现。在程序上,我们可以采用版本号机制或者时间戳机制实现。

    • 乐观锁的版本号机制

    在表中设计一个版本字段 version,第一次读的时候,会获取 version 字段的取值。然后对数据进行更新或删除操作时,会执行UPDATE ... SET version=version+1 WHERE version=version。此时如果已经有事务对这条数据进行了更改,修改就不会成功。

    • 乐观锁的时间戳机制

    时间戳和版本号机制一样,也是在更新提交的时候,将当前数据的时间戳和更新之前取得的时间戳进行比较,如果两者一致则更新成功,否则就是版本冲突。

    悲观锁

    悲观锁(Pessimistic Locking)也是一种思想,对数据被其他事务的修改持保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排它性。

    0b6726dc504ec5beca81f91ae0333e89.png

    适用场景

    • 乐观锁适合读操作多的场景,相对来说写的操作比较少。它的优点在于程序实现,不存在死锁问题,不过适用场景也会相对乐观,因为它阻止不了除了程序以外的数据库操作。
    • 悲观锁适合写操作多的场景,因为写的操作具有排它性。采用悲观锁的方式,可以在数据库层面阻止其他事务对该数据的操作权限,防止读 - 写和写 - 写的冲突。

    总结

    乐观锁和悲观锁并不是锁,而是锁的设计思想。

    避免死锁的发生:

    • 如果事务涉及多个表,操作比较复杂,那么可以尽量一次锁定所有的资源,而不是逐步来获取,这样可以减少死锁发生的概率;
    • 如果事务需要更新数据表中的大部分数据,数据表又比较大,这时可以采用锁升级的方式,比如将行级锁升级为表级锁,从而减少死锁产生的概率;
    • 不同事务并发读写多张数据表,可以约定访问表的顺序,采用相同的顺序降低死锁发生的概率

    首发公众号:码农架构

    展开全文
  • 本文笔者经过对知识理解和整理后的一个总结,希望能够帮助朋友们对Java内存模型有更加清晰的认识,对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步。下面将从以下三点展开讨论:内存模型的由来内存...

    导读:近期笔者在阅读《深入理解Java虚拟机:JVM高级特性与最佳实现(第3版)》,书中提到关于Java内存模型的知识点,但是看完之后还是感觉有些模糊,便查阅一些其他相关资料。本文是笔者经过对知识理解和整理后的一个总结,希望能够帮助朋友们对Java内存模型有更加清晰的认识,对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步。下面将从以下三点展开讨论:

    • 内存模型的由来
    • 内存模型的定义
    • Java内存模型及实现

    内存模型的由来

    1、计算机在执行程序的时候每条指令都是由CPU来执行的。而CPU在执行的时候为了获取数据,所以难免与主存打交道。

    5956e70369f2e44e550cb1dc810ded1c.png

    2、随着CPU技术的发展其执行越来越高速度,越来也快,同时因内存技术发展比较缓慢,性能没有太大的变化,所以导致出现CPU每次操作内存都需要耗费一定的等待时间。

    67d4baaac41f6fed93ce86c221b5f27a.png

    3、为在保证CPU技术发展同时优化解决这一问题,人们后来想出来了一个方案,就是在CPU和内存之间增加高速缓冲存储器(Cache)。

    高速缓冲存储器是存在于主存与CPU之间的一级存储器, 由静态存储芯片(SRAM)组成,容量比较小但速度比主存高得多, 接近于CPU的速度。在计算机存储系统的层次结构中,是介于中央处理器和主存储器之间的高速小容量存储器。它和主存储器一起构成一级的存储器。高速缓冲存储器和主存储器之间信息的调度和传送是由硬件自动进行的。

    4a14d061ec4f6621249d46590838f05a.png

    因为Cache速度接近于CPU的速度且CPU每次操作主存前都会先访问Cache,所以通过增加Cache后当便达到了优化的效果。

    4、随着CPU的升级,一层缓存慢慢地无法满足要求,因此逐渐地衍生出多级缓存。每一级缓存中所储存的全部数据都是下一级缓存的一部分。而CPU读取数据也演变为:当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从下一级缓存查直到访问内存。如下图所示

    813f995a2ae063c40c8e152122f5c6fc.png

    5、单核CPU只含有一套L1,L2,L3缓存;如果CPU含有多个核心,即多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存,下图是一个单CPU双核得缓存结构图:

    6d8514421f6ec02674aca0904cd0a729.png

    随着计算机能力不断提升,开始支持多线程,那么就可能会问题了。我们分别来分析下单线程、多线程在单核CPU、多核CPU中的影响。

    1. 单核cpu与单线程:核心的缓存只被一个线程访问,缓存独占,不会出现访问冲突等问题
    2. 单核CPU与多线程:进程中的多个线程会同时访问进程中的共享数据,CPU将某块内存加载到缓存后,不同线程在访问相同的物理地址的时候,都会映射到相同的缓存位置,这样即使发生线程的切换,缓存仍然不会失效。但由于任何时刻只能有一个线程在执行,因此不会出现缓存访问冲突
    3. 多核CPU与多线程:每个核都至少有一个L1 缓存用于提升效率。当多个线程分别在不同的核心上执行且访问进程中的同个共享内存,由于多核是可以并行的,则可能会出现类似多线程编程中出现的并发问题,如对于同一块内存中的变量,多个核心同时读写修改数据的话,就会出现不可预期的错误,而其解决思路则是通过锁机制。

    所以在CPU和主存之间增加缓存,在多核CPU多线程场景下发生并发内存访问操作时可能会出现歧义。

    处理器优化--“指令重排”

    除了上面的问题之外,还有另一个硬件问题也比较重要:处理器为了使其内部的运算单元能够被充分利用会进行优化,可能会乱序执行处理输入代码,此处暂理解为“指令重排”。除了一些处理器会对代码进行优化乱序处理外,很多编程语言的编译器也会有类似的优化,比如Java虚拟机的JIT即时编译器也会做指令重排。

    82aa00c4906f0f52f2f63337025e8564.png

    如Java单例设计模式Double-Check例子中的voliate关键字应用就是为了防止因指令重排导致在多线程并发场景下出现异常。感兴趣的朋友可以参考我的另一篇文章深入解析单例模式--懒汉模式,这里就不再进行过多的探讨。

    什么是内存模型

    上面分析了那么多其实目的是为了引出两个重要问题

    • 多核CPU多线程场景下发生并发内存访问操作时可能会出现歧义
    • 处理器为了使其内部的运算单元能够被充分利用会自行进行优化--“指令重排”

    那么对于以上问题该如何解决?这时候便引出了重要概念--内存模型,定义如下:

    内存模型是对内存进行读写访问过程的抽象,可以理解为内存模型定义了共享内存系统中读写操作行为的规范,通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。它与处理器有关、与缓存有关、与并发有关、与编译器也有关。目的是为解决CPU多级缓存、处理器优化、指令重排等导致的问题与歧义,

    可以简单理解为内存模型其实就是解决多线程场景下因并发所导致的问题的一个重要规范

    8764619bcd353d2658b0ca5c0cf421fc.png

    Java内存模型

    1、定义

    Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,以实现让Java程序在各种平台下都能达到一致的内存访问效果的规范。

    2、理解

    Java内存模型(简称“JMM”)是一个规范,其主要目的是定义程序中各种变量的访问规则,是围绕着在并发过程中如何处理原子性可见性有序性三个特征来建立的。

    6ffe56d9538ca467151f33f5faed4416.png

    关于Java内存模型的实现,相信熟悉Java并发编程的朋友一定会熟悉,Java提供了一系列和并发处理相关的关键字,其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字,本文在这里就不对这些关键字一一展开讨论了,感兴趣的朋友可以看看《Java多线程编程核心技术》进行了解。其中如

    • 通过使用volatile关键字解决因指令重排导致的问题
    • 通过synchronized关键字来保证线程安全等

    等方式其实就与硬件通过计算机内存模型限制处理器优化使用内存屏障等解决问题的思路一致。

    928bef65d44847a5f84b2daa2364b020.png

    最后

    本文从硬件可能出现的问题引出计算机内存模型解决方案,进而提取出多线程并发问题。最后再引出Java内存模型。Java内存模型可以简单理解就是一套围绕着在并发过程中如何处理原子性、可见性和有序性三个特征来建立的规范,而如synchronized等关键字则是其具体实现。

    感谢您的阅读,如果喜欢本文欢迎关注和转发,本头条号将坚持原创,持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步

    参考文章及书籍:

    《深入理解Java虚拟机:JVM高级特性与最佳实现(第3版)》

    《Java多线程编程核心技术》

    HollisChuang 链接:https://juejin.im/post/5b42c01ee51d45194e0b819a

    展开全文
  • 字典的键字典中的值没有任何限制, 可以任意Python对象,即从标准对象到用户自定义对象皆可... 当有键发生冲突(即字典键重复赋值),取最后(最近)的赋值。Python并不会因字典中的键存在冲突而产生一个错误,它不会...

    字典的键

    字典中的值没有任何限制, 可以是任意Python对象,即从标准对象到用户自定义对象皆可,但是字典中的键是有类型限制的。

    (1)不允许一个键对应多个值 必须明确一条原则:每个键只能对应一个项。也就是说:一键对应多个值是不允许的(像列表、元组和其他字典这样的容器对象是可以的)。 当有键发生冲突(即字典键重复赋值),取最后(最近)的赋值。Python并不会因字典中的键存在冲突而产生一个错误,它不会检查键的冲突是因为如果真这样做的话,在每个键-值对赋值的时候都会做检查,这将会占用一定量的内存。

    >>> dict1 = {'foo':789, 'foo': 'xyz'}

    >>> dict1

    {'foo': 'xyz'}

    >>> dict1['foo'] = 123

    >>> dict1

    {'foo': 123}

    (2)键必须是可哈希的

    大多数Python对象可以作为键,但它们必须是可哈希的对象。像列表和字典这样的可变类型,由于它们不是可哈希的,所以不能作为键。

    所有不可变的类型都是可哈希的,因此它们都可以做为字典的键。要说明的是:值相等的数字表示相同的键,即整型数字1和浮点数1.0的哈希值是相同的,它们是相同的键。

    同时,也有一些可变对象(很少)是可哈希的,它们可以做字典的键,但很少见。举一个例子,一个实现了__hash__() 特殊方法的类。因为__hash__()方法返回一个整数,所以仍然是用不可变的值(做字典的键)。

    为什么键必须是可哈希的?解释器调用哈希函数,根据字典中键的值来计算存储你的数据的位置。如果键是可变对象,它的值可改变。如果键发生变化,哈希函数会映射到不同的地址来存储数据。如果这样的情况发生,哈希函数就不可能可靠地存储或获取相关的数据。选择可哈希的键的原因就是因为它们的值不能改变。

    数字和字符串可以被用做字典的键,元组是不可变的但也可能不是一成不变的,因此用元组做有效的键必须要加限制:若元

    组中只包括像数字和字符串这样的不可变参数,才可以作为字典中有效的键。

    示例:

    # vi userpw.py

    #!/usr/bin/env python

    db = {}

    def newuser():

    prompt= 'please regist your name: '

    while True:

    name = raw_input(prompt)

    if db.has_key(name):

    prompt = 'name taken,try another: '

    continue

    else:

    break

    pwd = raw_input('passswd: ')

    db[name] = pwd

    print 'Newuser [%s] has added successfully!' %name

    def olduser():

    name = raw_input('login: ')

    pwd = raw_input('passwd: ')

    passwd = db.get(name)

    if passwd == pwd:

    print 'welcome back',name

    else:

    print 'login incorrect!'

    def showmenu():

    prompt = '''

    (N)ew User Login

    (E)xisting User Login

    (Q)uit

    Enter choice: '''

    while True:

    try:

    choice = raw_input(prompt).strip()[0].lower()

    print '\nYou picked: [%s]' % choice

    if choice not in 'neq':

    print 'invalid option,please try again'

    if choice == 'n':

    newuser()

    if choice == 'e':

    olduser()

    if choice == 'q':

    break

    except(EOFError,KeyboardInterrupt):

    print 'invalid option,please try again'

    if __name__ == '__main__':

    showmenu()

    展开全文
  • SVN更新的时候前面的U、A、G、R、C是什么意思? U:表示从服务器收到文件更新了 G:表示本地文件以及服务器文件都已更新,而且成功的合并了 其他的如下: A:表示有文件或者目录添加到工作目录 R:表示文件或者目录被替换了...
  • 使用std命名空间98年以后的c++语言提供一个全局的命名空间namespace,可以避免导致全局命名冲突问题。...如果按照上述方式定义,那么这两个头文件不可能包含在同一个程序中,因为String类会发生冲突。所谓...
  • U:表示从服务器收到文件更新了  G:表示本地文件以及服务器文件都已更新,而且成功的合并了 ...C:表示文件的本地修改和服务器修改发生冲突   转载自:https://blog.csdn.net/yhj19920417/article/details/47441747...
  • U:表示从服务器收到文件更新了 G:表示本地文件以及服务器文件都已更新,而且成功的...C:表示文件的本地修改和服务器修改发生冲突 本文转自建波李 51CTO博客,原文链接:http://blog.51cto.com/jianboli/193970...
  • 重复定义了,这种情况很多时候是发生在头文件包含当中,比如你在一个头文件里面定义了 int week; 又在多个c文件当中包含了就会有命名冲突 因此,一般定义都放在.C文件当中,要是需要给其它模块用,就在头文件里面用...
  • 今天女朋友问我vue的生命周期合并策略是什么,我敲了敲她的小脑袋说(假装自己有女朋友): vue的生命周期是beforCreate,created,beforeMount等一大堆~如图: ...在合并时如果mixin的数据对象和组件的数据发生冲突时以...
  • 如果不关,第一次查询没问题的,可如果adoqury1再用一次的话,就会有肯能和上次发生冲突。 程序的不确定性很强,所以这样做有必要的,防止出现意想不到的问题。 还有一点就是节约内存,用过就关,不然会一直呆...
  • 关于git的使用在前端面试中很常见的题目,在实际工作中也经常会...比如当发生冲突的时候,或者需要暂时停止添加当前进行中的新feature开发,去修复一个bug,怎么保证既不影响当前工作,又能够顺利完成临时加派的任...
  • 当计算机使用过程中出现“计算机探测到IP地址与您的网卡物理地址发生冲突”的错误时,您就无法使用网络。此时,您可以做如下操作解决问题: 1、如果您使用的计算机的操作系统:windows 98等老系统 点击左下角...
  • force close意为强制关闭的意思指当前应用程序发生冲突。原因:比如空指针,角标溢出,Android API之间的顺序错误等等。解决方法:我们可以通过logcat查看抛出异常的位置,做相应的修改就行了。所以我们想避免...
  • 首先不要总将孩子当成小孩。一个女孩子,在日记中...青少年中与父母发生冲突的太多了。这到底怎么回事呢?父母还是那个父母,孩子还是那个孩子,也许说的话,也还是原来的话,原来的方式,可得到的效果为什么就...
  • 我们经常看见一句话:...因为子线程可能会有多个,多个线程同时操作一个控件可能会有冲突发生,所以android就限定了只有主线程可以操作UI。子线程想操作UI,可以,你告诉我(主线程),我来更新。    在一个Andr
  • this关键字是什么意思 有时一个方法需要引用调用它的对象。为此,java定义了this这个关键字。简单地说This是在对象内部指代自身的引用。可以直接引用对象,可以解决实例变量和局部变量之间发生的任何同名的冲突。 ...
  • 原因很简单但是却折磨了我好久,不懂什么意思最后终于知道了原因,我将该脚本名称起名为tensorflow.py,该名会和tensorflow库发生冲突所以需要你修改名称就可以了。提前你已经安装好了tensorfow。 下面大概...
  • NS是什么意思? Cocoa对其所有函数,常量和类型名前面都加了前缀"NS" ,这个前缀告诉你函数来自Cocoa而不是其他工具包。 好处:防止两个不同的事物因为名称一样而发生冲突。 NS的来历:Cocoa以前叫NeXtSTEP,是...
  • 在我们使用git的过程中很容易出现这样的问题,作为新手我们根本不知道发生什么? 报错意思:LF和CRLF都换行符,意思就是说git要把你的LF换行符全部换成CRLF这种换行符 产生原因:就是你用编辑器创建的项目LF换...
  • 0x00E23340 处有未经处理的异常(在 ...这是什么意思? 处理这段代码的时候出现问题: cin >> aN >> val; while (aN) { ps = new Savings(aN, val); cout ! \n"; cin >> aN >> val; } 不能循环啊,报错
  • 这个异常的意思是对资源合并发生错误,那就是我使用的图片资源有问题,我使用的图片能在android环境自适应展示的.9.png格式,在Eclipse上使用能通过编译的,但是为什么在android studio上就不能呢?原来,...
  • 一步步带你挑选机械键盘!

    千次阅读 2020-02-26 20:53:03
    无冲的意思是键盘可以多个按键同时使用,不会发生冲突。 键帽可以拆卸。 反应更加灵敏。 小劣势:防水防尘能力较差,不能沾水。 三、机械键盘有哪些分类?如何选择适合自己的机械键盘? 机械键盘按照 “轴” 的...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

发生冲突是什么意思