精华内容
下载资源
问答
  • VSCode配置 c++ 环境(小白教程)

    万次阅读 多人点赞 2020-01-28 16:26:48
    测试 后序 VSCode 一些好用的插件 VSCode 修改背景图片 VSCode 设置鼠标滚动改变字体大小 因为自己在VSCode配置过程中遇到许多问题,在此记录一下,希望能帮助到更多人 若需要彻底卸载重装VSCode,可查看此篇教程 ...

    因为自己在VSCode配置过程中遇到许多问题,在此记录一下,希望能帮助到更多人

    若需要彻底卸载重装VSCode,可查看此篇教程

    配置c++环境

    前言


    • 本人环境:Windows10 64位
    • VSCode 使用起来还是很方便的,运行速度快,占用系统资源小,还有丰富的插件

    软件安装


    1. 下载安装MinGW-w64及环境变量配置

    MinGW:可以理解成包含多种编译环境的可自由选择安装的其中的部分的软件

    • 下载地址:https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/
      直接弹窗下载即可,下载完按照下面教程安装配置即可。
      在这里插入图片描述

    鉴于有很多人安装失败,我将 MinGW 安装文件放在了网盘,链接如下:
    链接:https://pan.baidu.com/s/1hng1o1ruDn11JlnQBq7xaw
    提取码:r823

    • 安装
      在这里插入图片描述
      安装完成后界面
      在这里插入图片描述

    • 下载相关文件(重要步骤)

      打开MinGW,勾选编译器软件

      • mingw32-gcc.bin(c语言文件编译器)
      • mingw32-gcc-g++.bin(c++语言编译器)
      • mingw32-gdb.bin(调试编译后文件)

    若在安装的时候报“找不到 xxx 库”的错误,可以重新勾选此库和dll文件

    在这里插入图片描述
    选择完后,点击 Installation > applychange,等待安装完就ok
    在这里插入图片描述

    对于 mingw32-gdb.bin 等下载失败问题,这里我把所需的三个文件放在网盘,下载后将自己没下载成功的对应文件放到 MinGW\bin 目录下即可,链接如下:
    链接:https://pan.baidu.com/s/1ZJFnR_MRkOTeufjKO4dLnw
    提取码:18rx

    • 添加环境变量
      • 右击 我的电脑 点击 属性
        在这里插入图片描述

      • 点击 高级系统设置
        在这里插入图片描述

      • 点击 环境变量
        在这里插入图片描述

      • 在系统变量中选择 Path新建
        在这里插入图片描述

      • bin地址 加入环境变量 (我的是 “D:\MinGW\bin”)
        在这里插入图片描述

      • 检测是否安装成功:命令提示符中输入 gcc -v ,若显示版本号则说明安装成功
        在这里插入图片描述

    2. 下载安装VSCode


    • 下载地址:https://code.visualstudio.com/Download
      在这里插入图片描述
      在这里插入图片描述

    配置过程

    1. VSCode插件安装


    安装完成后,打开软件

    • 下载中文插件
      在这里插入图片描述

    • 下载 c/c++ 插件
      在这里插入图片描述

      插件安装完成后 重启 VSCode

    2. 创建工作区


    • 新建一个文件夹(放 c++ 代码文件)
    • 点击文件打开建的文件夹(快捷键 Ctrl+k Ctrl+O)在这里插入图片描述

    3. 配置文件


    • 在此文件夹新建一个 .vscode 文件夹
      在这里插入图片描述

    • 在 .vscode 文件夹中新建三个文件

      • c_cpp_properties.json
      • launch.json
      • tasks.json
        在这里插入图片描述
    • 将下列代码复制到文件中

      务必根据自己的安装位置修改文件路径

      • c_cpp_properties.json

        “includePath” 路径获取方法 cmd 下输入: gcc -v -E -x c++ -
        在这里插入图片描述
        在这里插入图片描述
        修改 “includePath”"Path"
        将图示这几行代替其中路径即可

        “d:/mingw/include/**” 此条路径也根据你的路径修改加入即可

      {
          "configurations": [
              {
                  "name": "Win32",
                  "includePath": [
                      "${workspaceRoot}",
                      "d:/mingw/include/**",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++/mingw32",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++/backward",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../include",
                      "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include-fixed"
                  ],
                  "defines": [
                      "_DEBUG",
                      "UNICODE",
                      "__GNUC__=6",
                      "__cdecl=__attribute__((__cdecl__))"
                  ],
                  "intelliSenseMode": "msvc-x64",
                  "browse": {
                      "limitSymbolsToIncludedHeaders": true,
                      "databaseFilename": "",
                      "path": [
                          "${workspaceRoot}",
                          "d:/mingw/include/**",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++/mingw32",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include/c++/backward",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../include",
                          "d:/mingw/bin/../lib/gcc/mingw32/8.2.0/include-fixed"
                      ]
                  }
              }
          ],
          "version": 4
      }
      
      
      • launch.json
        根据自己路径修改 "miDebuggerPath"
      {  
          "version": "0.2.0",  
          "configurations": [  
              {  
                  "name": "(gdb) Launch", // 配置名称,将会在启动配置的下拉菜单中显示  
                  "type": "cppdbg",       // 配置类型,这里只能为cppdbg  
                  "request": "launch",    // 请求配置类型,可以为launch(启动)或attach(附加)  
                  "program": "${workspaceFolder}/exe/${fileBasenameNoExtension}.exe",// 将要进行调试的程序的路径  
                  "args": [],             // 程序调试时传递给程序的命令行参数,一般设为空即可  
                  "stopAtEntry": false,   // 设为true时程序将暂停在程序入口处,一般设置为false  
                  "cwd": "${workspaceFolder}", // 调试程序时的工作目录,一般为${workspaceFolder}即代码所在目录  
                  "environment": [],  
                  "externalConsole": true, // 调试时是否显示控制台窗口,一般设置为true显示控制台  
                  "MIMode": "gdb",  
                  "miDebuggerPath": "D:/MinGW/bin/gdb.exe", // miDebugger的路径,注意这里要与MinGw的路径对应  
                  "preLaunchTask": "g++", // 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc  
                  "setupCommands": [  
                      {   
      		    "description": "Enable pretty-printing for gdb",  
                          "text": "-enable-pretty-printing",  
                          "ignoreFailures": true  
                      }  
                  ]  
              }  
          ]  
      }
      
      • tasks.json
        直接复制粘贴即可,无需修改

        这里我顺便把 exe 的路径改了。在 “args” 中,需要进行修改可自行百度,此处我的会将编译生成的 exe 文件单独放在一个 exe文件夹 中
      在这里插入图片描述

      {
          "version": "2.0.0",
          "command": "g++",
          "args": [
              "-g",
              "${file}",
              "-o",
              "${workspaceFolder}/exe/${fileBasenameNoExtension}.exe"
          ], // 编译命令参数
          "problemMatcher": {
              "owner": "cpp",
              "fileLocation": [
                  "relative",
                  "\\"
              ],
              "pattern": {
                  "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                  "file": 1,
                  "line": 2,
                  "column": 3,
                  "severity": 4,
                  "message": 5
              }
          }
      }
      

    这里解释一下args中自定义 exe文件存放路径:
    ${workspaceFolder}: 当前工作路径
    exe: 自己建的文件夹
    ${fileBasenameNoExtension}: 当前文件的文件名,NoExtension意思就是不带后缀名,然后加个 .exe 就是当前的exe文件,也就是编译生成的 exe 文件
    上述路径放一起意思就编译生成的 exe 文件放在exe文件夹中, 把这条配置删除的话,编译生成的exe文件就默认放在了当前工作路径下。

    顺便说一下 vscode 中一些变量代表什么意思
    ${workspaceFolder} :表示当前workspace文件夹路径,也即/home/Coding/Test
    ${workspaceRootFolderName}:表示workspace的文件夹名,也即Test
    ${file}:文件自身的绝对路径,也即/home/Coding/Test/.vscode/tasks.json
    ${relativeFile}:文件在workspace中的路径,也即.vscode/tasks.json
    ${fileBasenameNoExtension}:当前文件的文件名,不带后缀,也即tasks
    ${fileBasename}:当前文件的文件名,tasks.json
    ${fileDirname}:文件所在的文件夹路径,也即/home/Coding/Test/.vscode
    ${fileExtname}:当前文件的后缀,也即.json
    ${lineNumber}:当前文件光标所在的行号
    ${env:PATH}:系统中的环境变量

    4. 测试


    • 新建一个 cpp 文件
      在这里插入图片描述
    • F5 编译,成功
      在这里插入图片描述

    后序

    VSCode 一些好用的插件


    • Bracket Pair Colorizer —— 为不同匹配括号提供不同的颜色高亮
      在这里插入图片描述

    • Markdown All in one —— 书写 Markdown 利器
      在这里插入图片描述

    • Path Intellisence —— 路径自动补齐
      在这里插入图片描述

    • vscode-icons —— 图标插件
      在这里插入图片描述

    VSCode 修改背景图片

    • 管理员权限启动 VSCode,安装 background 插件
      在这里插入图片描述Ctrl+P 打开搜索框,输入 settings.json
      在这里插入图片描述

    • settings.json

      {
          "editor.fontSize": 20,
          "editor.mouseWheelZoom": true,
          "window.zoomLevel": 0,
          "files.autoGuessEncoding": true,
      
          // background 的相关配置
          "update.enableWindowsBackgroundUpdates": true,
          "background.customImages": [
              "file:///D:/vscode/vscode_bg/bg.png"  // 图片地址
          ],
          "background.style": {
              "content":"''",
              "pointer-events":"none",
              "position":"absolute",  // 图片位置
              "width":"100%",
              "height":"100%",
              "z-index":"99999",
              "background.repeat":"no-repeat",
              "background-size":"25%,25%",  // 图片大小
              "opacity":0.2  // 透明度
          },
          "background.useFront": true,
          "background.useDefault": false,
          "workbench.iconTheme": "vscode-icons-mac", // 是否使用默认图片
      }
      

      修改图片地址即可
      这是我的背景图片😄
      在这里插入图片描述

    VSCode 设置鼠标滚动改变字体大小

    • settings.json 中加入 “editor.mouseWheelZoom”: true 即可,上面我已经加上了,使用 Ctrl+鼠标滚轮 即可实现字体放大缩小
      在这里插入图片描述

    热心同学写的文章,大家可以参考一下:VSCode配置 c++环境(小白教程)后续问题总结:g++: fatal error: -fuse-linker-plugin, but liblto_plugin-0.dll not found

    如果本文对你有小小的帮助,请点个赞再走呗😄

    展开全文
  • 小甲鱼零基础入门学习python笔记

    万次阅读 多人点赞 2019-08-14 11:06:30
    小甲鱼老师零基础入门学习Python全套资料百度云(包括小甲鱼零基础入门学习Python全套视频+全套源码+全套PPT课件+全套课后题及Python常用工具包链接、电子书籍等)请往我的资源...

    小甲鱼老师零基础入门学习Python全套资料百度云(包括小甲鱼零基础入门学习Python全套视频+全套源码+全套PPT课件+全套课后题及Python常用工具包链接、电子书籍等)请往我的资源(https://download.csdn.net/download/qq_32809093/13099592查看

    目录:

    000 愉快的开始
    001 我和Python的第一次亲密接触
    002 用Python设计第一个游戏
    003 小插曲之变量和字符串
    004 改进我们的小游戏
    005 闲聊之Python的数据类型
    006 Pyhon之常用操作符
    007 了不起的分支和循环
    008 了不起的分支和循环2
    009 了不起的分支和循环3
    010 列表:一个打了激素的数组
    011列表:一个打了激素的数组2
    012列表:一个打了激素的数组3
    013元组:戴上了枷锁的列表
    014字符串:各种奇葩的内置方法
    015字符串:格式化
    016 序列!序列!
    017函数:Python的乐高积木
    018 函数:灵活即强大
    019函数:我的地盘听我的(局部变量与全局变量)
    020函数:内嵌函数和闭包
    021函数:lambda表达式
    022 函数:递归是神马
    023 递归:这帮小兔崽子
    024 递归:汉诺塔
    025 字典:当索引不好用时
    026 字典:当索引不好用时2
    027 集合:在我的世界里,你就是唯一
    028 文件:因为懂你,所以永恒
    029 文件:一个任务
    030 文件系统:介绍一个高大上的东西
    031 永久存储:腌制一缸美味的泡菜(pickle)
    032 异常处理:你不可能总是对的
    033 异常处理:你不可能总是对的2
    034 丰富的else语句及简洁的with语句
    035 图形用户界面入门:EasyGui
    036 类和对象:给大家介绍对象
    037 类和对象:面向对象编程
    038 类和对象:继承
    039 类和对象:拾遗
    040 类和对象:一些相关的BIF
    041 魔法方法:构造和析构
    042 魔法方法:算术运算
    043 魔法方法:算术运算2
    044 魔法方法:简单定制
    045 魔法方法:属性访问
    046 魔法方法:描述符(Property的原理)
    047 魔法方法:定制序列
    048 魔法方法:迭代器
    049 乱入:生成器
    050 模块:模块就是程序
    051 模块:__name__='__main__'、搜索路径和包
    052 模块:像个极客一样去思考
    053 论一只爬虫的自我修养
    054 论一只爬虫的自我修养2:实战
    055 论一只爬虫的自我修养3:隐藏

    064 GUI的终极选择:Tkinter
    065 GUI的终极选择:Tkinter2
    066 GUI的终极选择:Tkinter3
    067 GUI的终极选择:Tkinter4
    068 GUI的终极选择:Tkinter5
    069 GUI的终极选择:Tkinter6
    070 GUI的终极选择:Tkinter7
    071 GUI的终极选择:Tkinter8
    073 GUI的终极选择:Tkinter10
    074  GUI的终极选择:Tkinter11
    075 GUI的终极选择:Tkinter12
    076 GUI的终极选择:Tkinter13
    077 GUI的终极选择:Tkinter14

    078 Pygame:初次见面,请大家多多关照

     

    000 愉快的开始

    python跨平台。
    应用范围:操作系统、WEB、3D动画、企业应用、云计算
    大家可以学到什么Python3的所有常用语法、面向对象编程思维、运用模块进行编程、游戏编程、计算机仿真

    Python 是脚本语言
    脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序。以简单的方式快速完成某些复杂的事情通常是创造脚本语言的重要原则,基于这项原则,使得脚本语言通常比 C 语言、C++语言 或 Java 之类的系统编程语言要简单容易。也让脚本语言另有一些属于脚本语言的特性:
    •  语法和结构通常比较简单
    •  学习和使用通常比较简单
    •  通常以容易修改程序的“解释”作为运行方式,而不需要“编译”
    •  程序的开发产能优于运行性能
    一个脚本可以使得本来要用键盘进行的相互式操作自动化。一个 Shell 脚本主要由原本需要在命令行输入的命令组成,或在一个文本编辑器中,用户可以使用脚本来把一些常用的操作组合成一组串行。主要用来书写这种脚本的语言叫做脚本语言。很多脚本
    语言实际上已经超过简单的用户命令串行的指令,还可以编写更复杂的程序。

    IDLE 是一个 Python Shell,shell 的意思就是“外壳”,基本上来说,就是一个通过键入文本与程序交互的途径!像我们 Windows 那个 cmd 窗口,像 Linux 那个黑乎乎的命令窗口,他们都是 shell,利用他们,我们就可以给操作系统下达命令。同样的,我们可以利用 IDLE 这个 shell 与 Python 进行互动。

    注:在 Python 中不能把两个完全不同的东西加在一起,比如说数字和文本

    如果我需要在一个字符串中嵌入一个双引号,正确的做法是:你可以利用反斜杠(\)对双引号转义:\",或者用单引号引起这个字符串

    001 我和Python的第一次亲密接触

    IDLE启动Python

    IDLE是一个Python Shellshell的意思就是“外壳”,基本上来说,就是一个通过键入文本与程序交互的途径

    我们看到>>>这个提示符,Ta的含义是告诉你,Python已经准备好了,在等着你键入Python指令呢

    好了,大家试试在IDLE里输入:

    >>>print (“I love fishc.com”)

    我们尝试点儿新的东西,我们输入

    >>>print(5+3)

    或者直接输入

    >>>5+3

    不妨在试试计算

    >>>1234567890987654321*987654321012345678

    还有我们可以将两个字符串“相加”在一起,这种做法叫做拼接字符串

    >>>print("well water"+"river")

    先试试

    >>> print("I love fishc.com"*2)

    >>> print("I love fishc.com\n"* 2)

    002 用Python设计第一个游戏

    实例1:

    print("---------我爱鱼C工作室----------")
    temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:")
    guess = int(temp)
    if guess == 8:
        print("我草,你是小甲鱼心里的蛔虫嘛?!")
        print("哼,猜中了也没有奖励!")
    else:
        print("猜错了,小甲鱼现在心里想的是8!")
        print("游戏结束,不玩啦")

    BIF 就是 Built-in Functions,内置函数。为了方便程序员快速编写脚本程序(脚本就是要编程速度快快快!!!),Python 提供了非常丰富的内置函数,我们只需要直接调用即可,例如 print() 的功能是“打印到屏幕”,input() 的作用是接收用户输入。

    在 Python 或 IDLE 中,输入 dir(__builtins__) 可以看到 Python 提供的内置方法列表(注意,builtins 前后是两个下划线哦)其中小写的就是 BIF。如果想具体查看某个BIF 的功能,比如 input(),可以在 shell 中输入 help(input),就会得到这个 BIF 的功能描述。哦,答案应该是 68 个

    >>> dir(__builtins__)  查看 Python 提供的内置方法列表

    >>> help(input)  查看input的具体使用说明 

    注:

    只有当标识符已经赋值后( Python 的变量是不用先声明的)才能在代码中使用,未赋值的标识符直接使用会导致运行时错误

    缩进是 Python 的灵魂

    Python 不允许 if 条件中赋值,所以 if c = 1: 会报错!

     

    003 小插曲之变量和字符串

    插曲之变量

    变量名就像我们现实社会的名字,把一个值赋值给一个名字时,Ta会存储在内存中,称之为变量(variable),在大多数语言中,都把这种行为称为“给变量赋值”或“把值存储在变量中”。

    不过Python与大多数其他计算机语言的做法稍有不同,Ta并不是把值存储在变量中,而更像是把名字贴在值的上边。

    所以有些Python程序员会说“Python”没有“变量”,只有“名字”。

    需要注意的地方

    在使用变量之前,需要对其先赋值。

    变量名可以包括字母、数字、下划线,但变量名不能以数字开头

    字母可以是大写或小写,但大小写是不同的。也就是说fishcFishC对于Python来说是完全不同的两个名字

    等号(=)是赋值的意思,左边是名字,右边是值,不可写反咯。

    插曲之字符串

    到目前为止,我们所认知的字符串就是引号内的一切东西,我们也把字符串叫做文本,文本和数字是截然不同的,咱看例子:>>>5+8

    >>> '5'+'8'

    要告诉Python你在创建一个字符串,就要在字符两边加上引号,可以是单引号或者双引号Python女士表示不挑剔。但必须成对,你不能一边单引号,另一边却花心的用上双引号结尾。

    如果字符串中需要出现单引号或双引号怎么办

    例如我想打印字符串:Let’s go!

    有两种方法,第一种比较常用,就是使用我们的转义符号(\)对字符串中的引号进行转义:

    >>> 'Let\'s go!'

    原始字符串

    好像反斜杠是一个好东西,但不妨试试打印:

    >>> str = 'C:\now'

    我们可以用反斜杠对自身进行转义:

    >>> str = 'C:\\now'

    原始字符串的使用非常简单,只需要在字符串前边加一个英文字母r即可(则都会以原始字符串输出):

    >>>str = r'C:\now'

    长字符串

    如果希望得到一个跨越多行的字符串,例如:

    我爱鱼C

    正如我爱小甲鱼,

    久久不肯散去……

    这我们就需要使用到三重引号字符串!

     

    004 改进我们的小游戏

    第一个改进要求:猜错的时候程序提示用户当前的输入比答案大了还是小了

    与操作and

    第二个改进要求:程序应该提供多次机会给用户猜测,专业点来讲就是程序需要重复运行某些代码。

    条件分支

    while循环

    实例1:找8

    temp = input("请输入一个数据:")
    guess = int(temp)
    i=0
    while guess != 8 and i < 3:
        i = i + 1
        temp = input("哎呀,猜错了,请重新输入吧:")
        guess = int(temp)
        if guess == 8:
            print("我草,你是小甲鱼心里的蛔虫嘛?")
            print("哼,猜对了也没有奖励")
        else:
            if guess > 8:
                print("哥,大了大了~~")
            else:
                print("嘿,小了!小了!!")
    print("游戏结束,不玩啦~~")

    random模块里边有一个函数叫做:randint()Ta会返回一个随机的整数。

    实例2:找随机数

    import random#导入随机数函数
    secret = random.randint(1,5)#随机生成1到5的一个随机数
    temp = input("请输入一个1-5的数据:")
    guess = int(temp)
    i=0
    while guess != secret and i < 6:
        i = i + 1
        guess = int(temp)
        if guess == secret:
            print("我草,你是小甲鱼心里的蛔虫嘛?")
            print("哼,猜对了也没有奖励")
        else:
            if guess > secret:
                print("哥,大了大了~~")
            else:
                print("嘿,小了!小了!!")      
            temp = input("请重新输入吧:")
    print("游戏结束,不玩啦~~")

     

    005 闲聊之Python的数据类型

    Python的一些数值类型:整型、布尔类型(True与False)、浮点型、e记法、复数类型等

    e记法(e4相当于10的四次方,e-10相当于10的-10次方)

    类型转换

    字符型转换为整型

    其它同上

    type()函数(可查看变量类型)

    isinstance()函数(用来判断两个输入参数类型是否一致)

     

    006 Pyhon之常用操作符

    算术操作符

    注:python中 \ 为除法, \\ 为整除 ,% 为取余

    幂运算(3的二次方)

    3的二次方后取负

    注:先幂运算、然后乘除、后加减、后逻辑

    3的负二次方

    比较操作符

    逻辑操作符

    优先级问题

    007 了不起的分支和循环

    打飞机游戏框架:

    加载背景音乐

    播放背景音乐(设置单曲循环)

    我方飞机诞生

    while True:
        if 用户是否点击了关闭按钮:
           推出程序
           
        interval += 1;
        if interval == 50:
           interval = 0;
           小飞机诞生
        小飞机移动一个位置
        屏幕刷新
        
        if 用户鼠标产生移动:
           我方飞机中心位置 = 用户鼠标位置
           屏幕刷新
           
        if 我方飞机与小飞机发生肢体冲突:
           我方挂,播放撞机音乐
           修改我方飞机图案
           打印“Game over"
           停止背景音乐,最好淡出

     

    008 了不起的分支和循环2

    现在小甲鱼来考考大家:

    按照100分制,90分以上成绩为A8090B6080C60以下为D,写一个程序,当用户输入分数,自动转换为ABCD的形式打印。

    score = int(input('请输入一个分数:'))
    if 100 >= score >= 90:
        print('A')
    elif 90 > score >= 80:
        print('B')
    elif 80 > score >= 60:
        print('C')
    elif 60 > score >= 0:
        print('D')
    else:
        print('输入错误!')

    条件表达式(三元操作符)

    有了这个三元操作符的条件表达式,你可以使用一条语句来完成以下的条件判断和赋值操作:

    x, y = 4, 5

    if x < y:

      small = x

    else:

      small = y

    例子可以改进为

    small = x if x < y else y    #如果x小于y,则small等于x,否则等于y

    断言(assert)

    assert这个关键字我们称之为“断言”,当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError的异常。

    举个例子:

    >>> assert 3 > 4

    一般来说我们可以用Ta再程序中置入检查点,当需要确保程序中的某个条件一定为真才能让程序正常工作的话,assert关键字就非常有用了

     

    009 了不起的分支和循环3

    while循环

    while 条件:

                      循环体

    for循环

    虽然说Python是由C语言编写而来的,但是Tafor循环跟C语言的for循环不太一样,Pythonfor循环显得更为智能和强大!

    语法:

    for 目标 in 表达式:

         循环体

    每次取FishC中一个字符及空格输出

    range()函数

    语法:range( [strat],[stop],[step] )

    这个BIF有三个参数,其中用中括号括起来的两个表示这两个参数是可选的。

    step=1表示第三个参数的值默认值是1setp为每步距离

    range这个BIF的作用是生成一个从start参数的值开始到stop参数的值结束的数字序列

     

    break语句(结束本层循环)

    实例:

    bingo = '小甲鱼是帅哥'
    answer = input('请输入小甲鱼最想听的一句话:')

    while True:
        if answer == bingo:
            break
        answer = input('抱歉,错了,请重新输入(答案正确才能退出游戏):')

    print('哎哟,帅哦~')
    print('您真是小甲鱼肚子里的蛔虫啊^_^')

    continue语句(当前位置结束本次循环,重新开始下次循环)

    实例:

    for i in range(10):
        if i%2 != 0:
            print(i)
            continue
        i += 2
        print(i)

    010 列表:一个打了激素的数组

    列表一个打了激素的数组

    创建列表

    创建一个普通列表

    创建一个混合列表

    创建一个空列表

    向列表添加元素

    append()函数向列表末尾添加一个元素

    extend()函数向列表末尾添加多个元素

    insert(n,xxx)函数向列表中第n个元素前插入一个元素

    注:0表示第一个元素

    011列表:一个打了激素的数组2

    从列表中获取元素

    跟数组一样,我们可以通过元素的索引值(index)从列表获取单个元素,注意,列表索引值是从 0 开始的。

    从列表删除元素

    remove()函数表示从列表中删除某个元素

    del()函数也表示从列表中删除某个元素

    pop()函数从列表中取出最后一个元素

    列表分片(Slice

    利用索引值,每次我们可以从列表获取一个元素,但是我们总是贪心的,如果一次性需要获取多个元素,有没有办法实现呢?利用列表分片,我们可以简单的实现这个要求。

    member[0:2]表示从第1个元素开始拷贝,一共拷贝两个元素,即member[0]和member[1]

    列表的拷贝

    012列表:一个打了激素的数组3

    列表的一些常用操作符

    比较操作符

    逻辑操作符

    连接操作符

    重复操作符

    成员关系操作符

    关于分片“拷贝”概念的补充

    >>> dir(list)可查看所有列表的操作函数

    count()函数可计算列表中相同元素个数

    index()函数可索引列表元素

    reverse()将列表中元素倒序

    sort()将列表中元素从小到大排序

    关于分片“拷贝”概念的补充

    注:list13=list11相当于多了个指向列表的标签,list12 = list[:]是实实在在的拷贝

    013元组:戴上了枷锁的列表

    由于和列表是近亲关系,所以元组和列表在实际使用上是非常相似的。

    我们这节课主要通过讨论元组和列表到底有什么不同来学习元组,酱紫大家就不会觉得老是重复一样的内容

    我们主要从以下几个点来讨论学习:

    创键和访问一个元组

    创建元组(括号可以没有,但逗号一定要有)

    访问元组前两个元素

    更新和删除一个元组

    更新一个元组

    注:其并未对原元组进行修改,而是生成了一个新的元组,并贴上temp名字标签而已。原元组由于标签没有了,则会被自动回收。

    删除一个元组

    元组相关的操作符

    注:元组不允许修改和删除。

    014字符串:各种奇葩的内置方法

     

    015字符串:格式化

    由于花括号被解释掉,所以不打印后面中文

    字符串格式化符号含义

    将ASCII码97对应的字符输出

    格式化整数

    格式化操作符辅助命令

    5表示输出为五位数

    Python 的转义字符及其含义

     

    016 序列!序列!

    列表、元组和字符串的共同点

    都可以通过索引得到每一个元素

    默认索引值总是从0开始

    可以通过分片的方法得到一个范围内的元素的集合

    有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)

    使用list方法

    元组转换为列表

    注:元组为小括号,列表为中括号。

    max() 返回序列或者参数集合中的最大值

    min() 返回序列或者参数集合中的最小值

    sum(iterable[,start=0]) 返回序列iterable和可选参数start的总和

    sorted()将元素从小到大重新排列

    reversed()将元素倒序排列

    注:元组是不可以修改和删除的,所以不可以直接对元组使用sorted与reversed命令

    enumerate()将每个元素插入枚举

    zip()返回由各个参数的序列组成的元组

     

    017函数:Python的乐高积木

    定义一个函数和调用

     

    018 函数:灵活即强大

    形参和实参

    >>> def MyFirstFunction(name):

      '函数定义过程中的name是叫形参'

      #因为Ta只是一个形式,表示占据一个参数位置

      print('传递进来的' + name + '叫做实参,因为Ta是具体的参数值!')

    >>> MyFirstFunction('小甲鱼')

    传递进来的小甲鱼叫做实参,因为Ta是具体的参数值!

    关键字参数

    默认参数(即形参中给定默认值,则在未给实参时会以默认值输出)

    收集参数

     

    019函数:我的地盘听我的

    函数与过程

    再谈谈返回值

    如果有返回值,函数则返回对应值;如果没有,则返回None

    可以返回多个值

    019函数:我的地盘听我的(局部变量与全局变量)

    def discounts(price, rate):
        final_price = price * rate
        old_price = 88 #这里试图修改全局变量
        print('修改后old_price的值是:', old_price)
        return final_price

    old_price = float(input('请输入原价:'))
    rate = float(input('请输入折扣率:'))
    new_price = discounts(old_price, rate)
    print('修改后old_price的值是:', old_price)
    print('打折后价格是:', new_price)

    global可将局部变量声明为全局变量

    020函数:内嵌函数和闭包

    内嵌函数

    闭包(closure

    注:使用nonlocal语句将x强制为不是局部变量

    021函数:lambda表达式

    lambda表达式的作用

    Python写一些执行脚本时,使用lambda就可以省下定义函数过程,比如说我们只是需要写个简单的脚本来管理服务器时间,我们就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简

    对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的问题了

    简化代码的可读性,由于普通的屌丝函数阅读经常要跳到开头def定义部分,使用lambda函数可以省去这样的步骤。

    过滤函数filter可筛选出非零元素

    筛选出奇数

    注:lambda x:x%2用来判断是否为奇,x为奇则输出1,否则输出0;range(10)可生成0-9的10个整数,filter用来筛选非零元素;如果为偶数,则被筛选掉;如果为奇数,则保留,但输出的是rang(10)产生的原始数,因为lambda只是用来判断是否为奇偶

    range生成的0-9给了x,x经过2倍运算后再赋值给x

    022 函数:递归是神马

    汉诺塔游戏

    树结构的定义

    谢尔宾斯基三角形

    递归求阶乘

    写一个求阶乘的函数

    正整数阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。

    例如所给的数是5,则阶乘式是1×2×3×4×5,得到的积是120,所以120就是4的阶乘。

    假设我们n的值传入是5,那么:

    实例:求阶乘

    def factorial(n):
        result = n
        for i in range(1, n):
            result *= i

        return result

    number = int(input('请输入一个正整数:'))
    result = factorial(number)
    print("%d 的阶乘是:%d"  % (number, result))#格式化为整数类型

    实例2:递归求阶乘

    def factorial(n):
        if n == 1:
            return 1
        else:
            return n * factorial(n-1)

    number = int(input('请输入一个正整数:'))
    result = factorial(number)
    print("%d 的阶乘是:%d" % (number, result))

    023 递归:这帮小兔崽子

    坑爹的兔子

    斐波那契数列的迭代实现

    我们都知道兔子繁殖能力是惊人的,如下图:

    我们可以用数学函数来定义:

    课间练习:假设我们需要求出经历了20个月后,总共有多少对小兔崽子?(迭代 vs 递归

    def fab(n):
        n1 = 1
        n2 = 1
        n3 = 1

        if n < 1:
            print('输入有误!')
            return -1

        while (n-2) > 0:
            n3 = n2 + n1
            n1 = n2
            n2 = n3
            n -= 1
        
        return n3

    result = fab(20)
    if result != -1:
        print('总共有%d对小兔崽子诞生!' % result)

    斐波那契数列的递归实现

    递归实现(递归计算时间将拉长)

    def fab(n):
        if n < 1:
            print('输入有误!')
            return -1

        if n == 1 or n == 2:
            return 1
        else:
            return fab(n-1) + fab(n-2)

    result = fab(35)
    if result != -1:
        print('总共有%d对小兔崽子诞生!' % result)

    注:迭代计算时间远比递归少,因为递归要循环出入栈

    024 递归:汉诺塔

    递归求解汉诺塔

     

    对于游戏的玩法,我们可以简单分解为三个步骤

    将前63个盘子从X移动到Y上。

    将最底下的第64个盘子从X移动到Z上。

    Y上的63个盘子移动到Z上。

    问题一:将X上的63个盘子借助Z移到Y上;

    问题二:将Y上的63个盘子借助X移到Z上。

     

    对于游戏的玩法,我们可以简单分解为三个步骤

    将前63个盘子从X移动到Y上。

    将最底下的第64个盘子从X移动到Z上。

    Y上的63个盘子移动到Z上。

    问题一:将X上的63个盘子借助Z移到Y上;

    问题二:将Y上的63个盘子借助X移到Z上。

    实例:

    def hanoi(n, x, y, z):
        if n == 1:
            print(x, ' --> ', z)
        else:
            hanoi(n-1, x, z, y) # 将前n-1个盘子从x移动到y上
            print(x, ' --> ', z) # 将最底下的最后一个盘子从x移动到z上
            hanoi(n-1, y, x, z) # 将y上的n-1个盘子移动到z上

    n = int(input('请输入汉诺塔的层数:'))
    hanoi(n, 'X', 'Y', 'Z')

    025 字典:当索引不好用时

    映射

    创建和访问字典

    >>> dict4 = dict(小甲鱼='让编程改变世界',李宁='一切皆有可能')
    >>> dict4
    {'小甲鱼': '让编程改变世界', '李宁': '一切皆有可能'}

    >>> dict4['爱迪生'] = '天才是99%的汗水加1%的灵感'
    >>> dict4
    {'小甲鱼': '让编程改变世界', '李宁': '一切皆有可能', '爱迪生': '天才是99%的汗水加1%的灵感'}

    026 字典:当索引不好用时2

    fromkey()方法用于创建并返回一个新的字典它有两个参数,第一个参数是字典的键;第二个参数是可选的,是传入键的值。如果不提供,默认是None

    >>> dict1 = {}
    >>> dict1.fromkeys((1,2,3))
    {1: None, 2: None, 3: None}
    >>> dict2 = {}
    >>> dict2.fromkeys((1,2,3),"Number")
    {1: 'Number', 2: 'Number', 3: 'Number'}
    >>> dict3 = {}
    >>> dict3.fromkeys((1,2,3),('one','two','three'))
    {1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}

    访问字典的方法有key()、values()和items()

    key()用于返回字典中的键,value()用于返回字典中所有的值,item()当然就是返回字典中所有的键值对(也就是项)

    >>> dict1 = dict1.fromkeys(range(5),'赞')
    >>> dict1.keys()
    dict_keys([0, 1, 2, 3, 4])
    >>> dict1.values()
    dict_values(['赞', '赞', '赞', '赞', '赞'])
    >>> dict1.items()
    dict_items([(0, '赞'), (1, '赞'), (2, '赞'), (3, '赞'), (4, '赞')])

    get()方法提供了更宽松的方式去访问字典项,当键不存在的时候,get()方法并不会报错,只是默默第返回一个None,表示啥都没找到:

    >>> dict1.get(10)
    >>> dict1.get(4)
    '赞'

    如果希望找不到数据时返回指定的值,可以在第二个参数设置对应的默认返回值:

    >>> dict1.get(32,'木有')
    '木有'

    如果不知道一个键是否在字典中,可以使用成员资格操作符(in 或 not in)来判断
    >>> 31 in dict1
    False
    >>> 4 in dict1

    clear()可清空一个字典

    >>> dict1
    {0: '赞', 1: '赞', 2: '赞', 3: '赞', 4: '赞'}
    >>> dict1.clear()
    >>> dict1
    {}

    copy()方法是复制字典(全拷贝)

    >>> a = {1:'one',2:'two',3:'three'}
    >>> b = a.copy()
    >>> id(a)
    52448840
    >>> id(b)
    52503624
    >>> a[1] = 'four'
    >>> a
    {1: 'four', 2: 'two', 3: 'three'}
    >>> b
    {1: 'one', 2: 'two', 3: 'three'}

    pop()是给定键弹出对应的值,popitem()是随机弹出一个项

    >>> a.pop(2)
    'two'
    >>> a
    {1: 'four', 3: 'three'}
    >>> a.popitem()
    (1, 'four')
    >>> a
    {3: 'three'}

    setdefault()方法与get()方法相似,但setdefault()在字典中找不到相应的键值时会自动添加

    >>> a = {1:'one',2:'two',3:'three'}
    >>> a.setdefault(2)
    'two'
    >>> a.setdefault(4)
    >>> a
    {1: 'one', 2: 'two', 3: 'three', 4: None}

    update()方法可以更新字典

    >>> a = {1:'one','小白':None}

    >>> b = {'小白':'狗'}
    >>> a.update(b)
    >>> a
    {1: 'one', '小白': '狗'}

    027 集合:在我的世界里,你就是唯一

    字典的表亲--集合(在python3中,如果用大括号括起一堆数字但没有体现映射关系,那么就会认为这堆玩意儿就是个集合)

    >>> num1 = {}
    >>> type(num1)
    <class 'dict'>
    >>> num2 = {1,3,4}
    >>> type(num2)
    <class 'set'>

    集合中的元素都是唯一的(集合会自动帮我们把重复的数据清理掉,集合是无序的,所以不能试图去索引集合中的某一个元素

    >>> num = {1,2,3,4,5,5,4,3,2,1}
    >>> num
    {1, 2, 3, 4, 5}

    如何创建一个集合有两种方法:1、直接把一堆元素用大括号括起来;2、用set()

    一种是直接把一堆元素用花括号括起来

    >>> set1 = {'小甲鱼','小鱿鱼','小甲鱼'}

    一种是使用set()工厂函数

    >>> set2 = set(['小甲鱼','小鱿鱼','小甲鱼'])
    >>> set1 == set2
    True

    课堂搞搞看

    要求:去掉列表中重复的元素

    [0, 1, 2, 3, 4, 5, 5, 3, 1]

    方法一、

    >>> list1 = [1,2,3,4,5,5,3,1,0]

    >>> temp = list1[:]
    >>> list1.clear()
    >>> list1
    []
    >>> for each in temp:
        if each not in list1:
            list1.append(each) #append()表示向列表中添加元素

    方法二、

    >>> list1 = list(set(list1))
    >>> list1
    [0, 1, 2, 3, 4, 5]

    #set(list1)先将list1列表转变为集合, list(set(list1))再讲集合转变为列表

    如何访问集合中的值

    由于集合中的元素是无序的,所以并不能像序列那样用下标来进行访问,但是可以使用迭代把集合中的数据一个个读取出来

    可以使用for把集合中的数据一个个读取出来

    >>> set1 = {1,2,3,4,5,4,3,2,1,0}
    >>> for each in set1:
        print(each,end = ' ')

        
    0 1 2 3 4 5 

    •也可以通过innot in判断一个元素是否在集合中已经存在

    >>> 0 in set1
    True
    >>> 8 in set1
    False

    使用add()方法可以为集合添加元素,使用remove()方法可以删除集合中已知的元素:

    >>> set1.add(6)
    >>> set1
    {0, 1, 2, 3, 4, 5, 6}
    >>> set1.remove(5)
    >>> set1
    {0, 1, 2, 3, 4, 6}

    不可变集合(把元素给froze冰冻起来)(像元组一样不能随意地增加或删除集合中的元素)

    028 文件:因为懂你,所以永恒

    大多数u程序都是:首先接收输入数据,然后按照要求进行处理,最后输出数据

    虽然当前数据放在内存中存取的速度要比硬盘中快,但一旦断电则会丢失,所以尽量ctrl+s保持到硬盘中


    什么是文件

    打开文件

    open(file, mode='r', buffering=-1, encoding=None,errors=None, newline=None, closefd=True, opener=None)

    open()的第一个参数是传入的文件名,第二个参数是指定文件的打开模式

    文件对象方法

    >>> f = open("D:\\python3.3.2\Hello.txt")
    >>> f
    <_io.TextIOWrapper name='D:\\python3.3.2\\Hello.txt' mode='r' encoding='cp936'>
    >>> f.read()
    "A. HISTORY OF THE SOFTWARE\n==========================\n\nPython was created in the early 1990s by Guido van Rossum at Stichting\nMathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands\nas a successor of a language called ABC.  Guido remains Python's\nprincipal author, although it includes many contributions from others.\n\nIn 1995, Guido continued his work on Python at the Corporation for\nNational Research Initiatives (CNRI, see http://www.cnri.reston.va.us)\nin Reston, Virginia where he released several versions of the\nsoftware."
    >>> f.close()
    >>> f = open("D:\\python3.3.2\Hello.txt")
    >>> f.read(5)
    'A. HI'
    >>> f.tell()   #返回当前光标所在文件的位置
    5
    >>> f.readline()
    'STORY OF THE SOFTWARE\n'
    将f放入到列表

    >>> f = open("D:\\python3.3.2\Hello.txt",'w')#w模式写入会覆盖已存在的文件(即原文件内容全部被删除),a模式则在末尾追加写入
    >>> f.write('who are you')          #返回的是写入的字符数
    11
    >>> f.close()

    029 文件:一个任务

    任务:将文件(record.txt)中的数据进行分割并按照以下规律保存起来:

    小甲鱼的对话单独保存为boy_*.txt的文件(去掉“小甲鱼:”)

    小客服的对话单独保存为girl_*.txt的文件(去掉“小客服:”)

    文件中总共有三段对话,分别保存为boy_1.txt, girl_1.txtboy_2.txt, girl_2.txt, boy_3.txt, gril_3.txt6个文件(提示:文件中不同的对话间已经使用“==========分割

    test1:

    f = open("record.txt")

    boy = []
    girl = []
    count = 1

    for each_line in f:
        if each_line[:6] != '======':#判断是否连续读到六个=
            (role,line_spoken) = each_line.split(':',1)#split以:进行字符切割,
            #将切得到的两部分内容依次存放在role与line_spoken中
            if role == '小甲鱼':
                boy.append(line_spoken)#将小甲鱼说的内容添加到列表boy中
            if role == '小客服':
                girl.append(line_spoken)#将小客服说的内容添加到列表girl中
        else:
            file_name_boy = 'boy_' + str(count) + '.txt'
            file_name_girl = 'girl_' + str(count) + '.txt'

            boy_file = open(file_name_boy,'w')#以w模式新建一个以file_name_boy命名的txt文件
            girl_file = open(file_name_girl,'w')#并贴上boy_file的标签

            boy_file.writelines(boy)#将列表boy中的内容写入到boy_file文件中
            girl_file.writelines(girl)

            boy_file.close()#关闭boy_file文件
            girl_file.close()

            boy = []#清空列表boy
            girl = []
            count += 1

    file_name_boy = 'boy_' + str(count) + '.txt'
    file_name_girl = 'girl_' + str(count) + '.txt'

    boy_file = open(file_name_boy,'w')
    girl_file = open(file_name_girl,'w')

    boy_file.writelines(boy)
    girl_file.writelines(girl)

    boy_file.close()
    girl_file.close()#记得关闭文件

    test2:

     

    def save_file(boy,girl,count):
        file_name_boy = 'boy_' + str(count) + '.txt'
        file_name_girl = 'girl_' + str(count) + '.txt'

        boy_file = open(file_name_boy,'w')
        girl_file = open(file_name_girl,'w')

        boy_file.writelines(boy)
        girl_file.writelines(girl)

        boy_file.close()
        girl_file.close()

    def split_file(file_name):
        f = open(file_name)

        boy = []
        girl = []
        count = 1

        for each_line in f:
            if each_line[:6] != '======':
                (role,line_spoken) = each_line.split(':',1)#split以:进行字符切割,
                #将切得到的两部分内容依次存放在role与line_spoken中
                if role == '小甲鱼':
                    boy.append(line_spoken)
                if role == '小客服':
                    girl.append(line_spoken)
            else:
                save_file(boy,girl,count)

                boy = []
                girl = []
                count += 1


        save_file(boy,girl,count)
        f.close()

    split_file('record.txt')

    030 文件系统:介绍一个高大上的东西

    os模块中关于文件/目录常用的函数使用方法

    >>> import os
    >>> os.getcwd()
    'D:\\python3.3.2\\小甲鱼python\\python程序\\第二十九课'

    >>> os.listdir('D:\\python3.3.2\\小甲鱼python\\python程序\\第二十九课')
    ['boy_1.txt', 'boy_2.txt', 'boy_3.txt', 'girl_1.txt', 'girl_2.txt', 'girl_3.txt', 'record.txt', 'test.py', 'test2.py']

    os.path模块中关于路径常用的函数使用方法

     >>> os.path.getsize('python.exe')  #获取文件的尺寸,返回值以字节为单位


    031 永久存储:腌制一缸美味的泡菜(pickle)

    python提供了一个标准的模块pickle可以非常容易地将列表、字典这类复杂的数据类型存储为文件。它几乎可以把所有python的对象都转化为二进制的形式存放,这个过程称为pickling,从二进制转换回对象的过程称为unpickling

    pickling过程

    >>> import pickle
    >>> my_list = [123,3,14,'小甲鱼',['another list']]

    >>> pickle_file = open('D:\\python3.3.2\小甲鱼python\python程序\第三十节课\my_list.pkl','wb')  #二进制写形式打开文件
    >>> pickle.dump(my_list,pickle_file)
    >>> pickle_file.close()

    unpickling过程       

    >>> import pickle
    >>> pickle_file = open('D:\\python3.3.2\小甲鱼python\python程序\第三十节课\my_list.pkl','rb')#以二进制读形式打开文件
    >>> my_list = pickle.load(pickle_file)
    >>> print(my_list)
    [123, 3, 14, '小甲鱼', ['another list']]

    实例:城市天气打包

    >>> pickle_file = open('D:\\python3.3.2\小甲鱼python\python程序\第三十一节课\city_data.pkl','wb')
    >>> pickle.dump(city,pickle_file)
    >>> pickle_file.close()

    032 异常处理:你不可能总是对的

    实例1:

    file_name = input('请输入需要打开的文件名:')
    file = open(file_name)
    print('文件的内容是:')
    for each_line in file:
        print(each_line)
    file.close()

    注:py文件与要打开的文件在同一个文件下则不需要加路径

    Python标准异常总结

    以下是 Python 内置异常类的层次结构:

            

    033 异常处理:你不可能总是对的2

    try-except语句

    try:

      检测范围

    except Exception[as reason]:

      出现异常(Exception)后的处理代码

    实例1:

    try:
        f = open('TE.txt')
        print(f.read())
        f.close()
    except OSError:
        print('文件打开过程中出错了!!!')

    实例2:

    try:
        f = open('TE.txt')
        print(f.read())
        f.close()
    except OSError as reason:
        print('文件打开出错原因是:\n' + str(reason))

    实例3:

    try:
        sum = 1 + '1'
        f = open('TE.txt')
        print(f.read())
        f.close()
    except OSError as reason:
        print('文件打开出错原因是:\n' + str(reason))
    except TypeError as reason:
        print('类型出错原因是:\n' + str(reason))

    实例4(多个异常统一处理):

    try:
        sum = 1 + '1'
        f = open('TE.txt')
        print(f.read())
        f.close()
    except(OSError, TypeError):
        print('出错了')

    注:try语句一旦检测到异常,剩下的语句将不会被执行

    try-finally语句

    try:

      检测范围

    except Exception[as reason]:

      出现异常(Exception)后的处理代码

    finally:

      无论如何都会被执行的代码

    实例5:

    try:
        f = open('test.txt')
        print(f.read())
        sum = 1 + '1'
    except (OSError,TypeError)as reason:
        print('出错了\n原因是:' + str(reason))
    finally:
        f.close()

    raise语句可以自己抛出一个异常

    034 丰富的else语句及简洁的with语句

    丰富的else语句

    要么怎样,要么不怎样

    if 条件:
        条件为真执行
    else:
        条件为假执行
          

    干完了能怎样,干不完就别想怎样

    实例1:

    def showMaxFactor(num):
        count = num // 2#//为整除,判断是素数,只需依次判断当前数num除以1到(num // 2)都不能整除即可
        while count > 1:
            if num % count == 0:#判断是否整除
                print('%d最大的约数是%d' % (num, count))
                break#跳出循环后else并不执行
            count -= 1
        else:#当while循环不成立时,或者理解为while循环完全被执行完了,没有给中途跳出(即break)
            print('%d是素数!' % num)

    num = int(input('请输入一个数:'))
    showMaxFactor(num)

    注:else与for语句搭配与while语句相同

    没有问题?那就干

    只要try语句块里没有出现任何异常,那么就会执行else语句块里的内容啦

    实例2:

    try:#尝试运行以下程序
        print(int('abc'))
    except ValueError as reason:#如果程序有异常时
        print('出错了:' + str(reason))
    else:#程序无异常时
        print('没有任何异常!')

    实例3:

    try:
        print(int('123'))
    except ValueError as reason:
        print('出错了:' + str(reason))
    else:
        print('没有任何异常!')

    简洁的with语句(with会自动帮你关闭文件)

    实例4:

    try:
        with open('test.txt','w') as f:
            for each_line in f:
                print(each_line)
    except (OSError,TypeError) as reason:
        print('出错了\n原因是:' + str(reason))

    035 图形用户界面入门:EasyGui

    图形用户界面编程,也就是平时常说的GUI(Graphical User  Interface),python有一个非常简单的GUI工具包:EasyGui

    GUI的安装

    导入方法一:

    >>> import easygui         #导入EasyGui
    >>> easygui.msgbox('嗨,亦我飞也')

    导入方法二:

    >>> from easygui import *
    >>> msgbox('嗨,亦我飞也')

    导入方法三(推荐使用):

    >>> import easygui as g
    >>> g.msgbox('嗨,亦我飞也')

    显示图片(注:图片需要为GIF格式,且存放在python.exe通目录

    >>> easygui.buttonbox(msg='你喜欢以下哪种水果',title='亦我飞也',choices=('草莓','西瓜','芒果'),image='aa.gif')

    实例1:

    import easygui as g
    import sys
     
    while 1:
        g.msgbox("嗨,欢迎进入第一个界面小游戏")
        msg = "请问你希望在鱼C工作室学习到什么知识呢"
        title="小游戏互动"
        choices=["谈恋爱","编程","OOXX","琴棋书画"]
        choice=g.choicebox(msg,title,choices)
     
        #note that we convert choice to string,in case
        #the user cancelled the choice,and we got None
        g.msgbox("你的选择是:"+str(choice),"结果")
        msg="你希望重新开始小游戏吗?"
        title=" 请选择"
        if g.ccbox(msg,title):  #show a Contiue/Cancel dialog
            pass #user chose Contonue
        else:
            sys.exit(0)  #user chose Cancel

    修改窗口大小(choicebox)

    修改文字大小(PROPORTIONAL_FONT)

    036 类和对象:给大家介绍对象

    给大家介绍对象

    把乱七八糟的数据扔进列表里,称数据层面的封装

    把常用的代码段打包成一个函数,称语句层面的封装

    把数据和代码都封装在一起,称对象层面的封装

    对象 = 属性 + 方法

    对象可以从静态(属性)动态(方法)两个特征来描述

    OO(面向对象)的特征

    继承

    class Turtle: # Python 中的类名约定以大写字母开头
        """关于类的一个简单例子"""
        # 属性
        color = 'green'
        weight = 10
        legs = 4
        shell = True
        mouth = '大嘴'

        # 方法
        def climb(self):
            print("我正在很努力的向前爬......")

        def run(self):
            print("我正在飞快的向前跑......")

        def bite(self):
            print("咬死你咬死你!!")

        def eat(self):
            print("有得吃,真满足^_^")

        def sleep(self):
            print("困了,睡了,晚安,Zzzz")

    调用类中的方法:

    >>> tt = Turtle()     #声明tt对象继承Turtle()
    >>> tt.climb()
    我正在很努力的向前爬......
    >>> tt.bite()
    咬死你咬死你!!

    定义一个带列表类MyList,将list2对象继承于它,则列表的功能继承它的对象都可以使用

    >>> class MyList(list):
        pass

    >>> list2 = MyList()

    >>> list2.append(5)
    >>> list2.append(6)

    >>> list2.append(1)
    >>> list2
    [5, 6, 1]
    >>> list2.sort()
    >>> list2
    [1, 5, 6]

    多态(下例中都调用的名字相同的方法,但实现不一样)

    >>> class A:
        def fun(self):
            print('我是小A。。。')

            
    >>> class B:
        def fun(self):
            print('我是小B。。。')

            
    >>> a = A()
    >>> b = B()
    >>> a.fun()
    我是小A。。。
    >>> b.fun()
    我是小B。。。

    037 类和对象:面向对象编程

    self是什么?

    Python的self其实就相当于C++的this指针。由同一个类可以生产无数对象,当一个对象的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,那么python就知道需要操作哪个对象的方法了。

    >>> class Ball:
        def setName(self,name):
            self.name = name
        def kick(self):
            print('我叫%s,该死的,谁踢我。。。' % self.name)

            
    >>> a = Ball()

    >>> a.setName('球A')
    >>> b = Ball()

    >>> b.setName('球B')

    >>> a.kick()
    我叫球A,该死的,谁踢我。。。
    >>> b.kick()
    我叫球B,该死的,谁踢我。。。

    你听说过Python的魔法方法吗?

    python的这些具有魔法的方法,总是被双下划线所包围,例如__init__(),即构造方法,也称构造函数,这个方法会在对象被创建时自动调用。其实,实例化对象时是可以传入参数的,这些参数会自动传入__init__()方法中,可以通过重写这个方法来自定义对象的初始化操作

    实例:

    >>> class Ball():
        def __init__(self,name):
            self.name = name
        def kick(self):
            print('我叫%s,该死的,谁踢我。。。' % self.name)

            
    >>> b = Ball('小土豆')
    >>> b.kick()
    我叫小土豆,该死的,谁踢我。。。

    公有和私有?python内部采用了一种叫 name mangling(名字改编)的技术

    默认上对象的属性和方法都是公开的,可以直接通过点操作符(.)进行访问:

    >>> class Person:
        name = '亦我飞也'

        
    >>> p = Person()
    >>> p.name
    '亦我飞也'

    为了实现定义私有变量,只需要在变量名或函数名前加上"__"两个下划线,那么这个函数或变量就会变成私有的了:

    私有变量不可以直接由外部访问

    >>> class Person:
        __name = '亦我飞也'

        
    >>> p = Person()
    >>> p.__name
    Traceback (most recent call last):
      File "<pyshell#65>", line 1, in <module>
        p.__name
    AttributeError: 'Person' object has no attribute '__name'

    室友变量可以由内部(内部函数)进行访问

    >>> class Person:
        __name = '亦我飞也'
        def getName(self):
            return self.__name

        
    >>> p = Person()
    >>> p.__name
    Traceback (most recent call last):
      File "<pyshell#72>", line 1, in <module>
        p.__name
    AttributeError: 'Person' object has no attribute '__name'

    >>> p.getName()
    '亦我飞也'

    其实,name mangling(名字改编)技术,只是把双下划线开头的变量进行了改名而已。实际上在外部使用“_类名__变量名“即可访问双下划线开头的私有变量了

    >>> p._Person__name
    '亦我飞也'

    038 类和对象:继承

    继承

                      子类                              父类

    class DerivedClassName(BaseClassName):

    ……

    实例:一个子类可以继承它的父类的所有属性和方法

    >>> class Parent:
        def hello(self):
            print('正在调用父类的方法。。。')

            

    >>> class Child(Parent):    #子类继承父类
        pass     #直接往下执行

    >>> p = Parent()
    >>> p.hello()
    正在调用父类的方法。。。
    >>> c = Child()
    >>> c.hello()
    正在调用父类的方法。。。

    如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法和属性(即子类方法属性改变,父类是不变的)

    >>> class Child(Parent):
        def hello(self):
            print('正在调用子类的方法')

            
    >>> c = Child()
    >>> c.hello()
    正在调用子类的方法
    >>> p.hello()
    正在调用父类的方法。。。

    实例2:

    import random as r
    class Fish:
        def __init__(self):
            self.x = r.randint(0,10)
            self.y = r.randint(0,10)

        def move(self):
            self.x -= 1
            print('我的位置是:',self.x,self.y)


    class Goldfish(Fish):
        pass

    class Garp(Fish):
        pass

    class Shark(Fish):
        def __init__(self):
            self.hungry = True

        def eat(self):
            if self.hungry:
                print('吃货的梦想就是天天有的吃')
                self.hungry = False
            else:
                print('太撑了,吃不下了!')

    >>> fish = Fish()
    >>> fish.move()
    我的位置是: -1 10
    >>> fish.move()
    我的位置是: -2 10
    >>> goldfish = Goldfish()
    >>> goldfish.move()
    我的位置是: 2 3
    >>> goldfish.move()
    我的位置是: 1 3
    >>> shark = Shark()
    >>> shark.eat()
    吃货的梦想就是天天有的吃
    >>> shark.eat()
    太撑了,吃不下了!
    >>> shark.move()    #报错原因时因为子类重写构造函数,覆盖了父类D的构造函数
    Traceback (most recent call last):
      File "<pyshell#9>", line 1, in <module>
        shark.move()
      File "D:\python3.3.2\小甲鱼python\python程序\第三十八节课\fish.py", line 8, in move
        self.x -= 1
    AttributeError: 'Shark' object has no attribute 'x'

    注:继承父类属性的子类,其变量值只属于当前子类,是子类的局部变量

    报错修改部分解决方法一:调用未绑定的父类方法

    >>> shark = Shark()
    >>> shark.move()
    我的位置是: 2 1
    >>> shark.move()
    我的位置是: 1 1

    报错修改部分解决方法二:使用super函数super函数会帮我们自动找到基类的方法,而且还自动为我们传入self参数

    >>> shark = Shark()
    >>> shark.move()
    我的位置是: 1 1
    >>> shark.move()
    我的位置是: 0 1

    多重继承

    class DerivedClassName(Base1, Base2, Base3):

    ……

    实例:子类c同时继承基类Base1和基类Base2

    >>> class Base1:
        def fool1(self):
            print('我是fool1,我为Base1代言。。。')

            
    >>> class Base2:
        def fool2(self):
            print('我是fool2,我为Base2代言。。。')

            
    >>> class C(Base1,Base2):
        pass

    >>> c = C()
    >>> c.fool1()
    我是fool1,我为Base1代言。。。
    >>> c.fool2()
    我是fool2,我为Base2代言。。。

    039 类和对象:拾遗

    组合(将需要的类一起进行实例化并放入新的类中)

    实例:

    class Turtle:
        def __init__(self,x):
            self.num = x

    class Fish:
        def __init__(self,x):
            self.num = x

    class Pool:
        def __init__(self,x,y):
            self.turtle = Turtle(x)
            self.fish = Fish(y)

        def print_num(self):
            print('水池里一共有乌龟 %d 条,鱼 %d 条' % (self.turtle.num,self.fish.num))

    >>> pool = Pool(5,2)
    >>> pool.print_num()
    水池里一共有乌龟 5 条,鱼 2 条

    现在要求定义一个类,叫水池,水池里要有乌龟和鱼。

    类、类对象和实例对象

    以下例子可见,对实例对象c的count属性赋值后,就相当于覆盖了类对象C的count属性。如果没有赋值覆盖,那么引用的是类对象的count属性

    >>> a = C()
    >>> b = C()
    >>> c = C()
    >>> print(a.count,b.count,c.count)
    0 0 0
    >>> c.count += 10
    >>> print(a.count,b.count,c.count)
    0 0 10
    >>> C.count += 100
    >>> print(a.count,b.count,c.count)
    100 100 10

    另外,如果属性的名字跟方法名相同,属性会覆盖方法:

    >>> class C:
        def x(self):
            print('X-man')

            
    >>> c = C()
    >>> c.x()
    X-man
    >>> c.x = 1              #新定义对象c的一个x属性,并赋值为1
    >>> c.x
    1
    >>> c.x()     #可见,方法x()已经被属性x给覆盖了
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        c.x()
    TypeError: 'int' object is not callable

    结论:不要试图在一个类里边定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展;用不同的词性命名,如属性名用名词、方法名用动词,并使用骆驼命名法等。

    到底什么是绑定?

    实例1:(python严格要求需要有实例才能被调用,即绑定概念)

    >>> class BB:
        def printBB():        #缺少self,导致无法绑定具体对象
            print('no zuo no die')

            
    >>> BB.printBB()
    no zuo no die
    >>> bb = BB()
    >>> bb.printBB()        #出现错误原因是由于绑定机制,自动把bb对象作为第一个参数传入
    Traceback (most recent call last):
      File "<pyshell#15>", line 1, in <module>
        bb.printBB()
    TypeError: printBB() takes 0 positional arguments but 1 was given

     

    Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念。

    040 类和对象:一些相关的BIF

    一些相关的BIF

    issubclass(class, classinfo)  如果第一个参数(class)是第二个参数(classinfo)的一个子类,则返回True,否则返回False

    >>> class A:
        pass

    >>> class B(A):
        pass

    >>> issubclass(B,A)
    True
    >>> issubclass(B,B)   #一个类被认为是其自身的子类
    True
    >>> issubclass(B,object)      # object是所有类的基类
    True
    >>> class C:
        pass

    >>> issubclass(B,C)
    False

    isinstance(object, classinfo)  如果第一个参数(object)是第二个参数(classinfo)的实例对象,则返回True,否则返回False

    >>> issubclass(B,C)       注:第一个参数如果不是对象,则永远返回False
    False
    >>> b1 = B()
    >>> isinstance(b1,B)
    True
    >>> isinstance(b1,C)
    False
    >>> isinstance(b1,A)
    True
    >>> isinstance(b1,(A,B,C))
    True

    hasattr(object, name)  用来测试一个对象里是否有指定的属性,第一个参数(object)是对象,第二个参数(name)是属性名(属性的字符串名字)

    >>> class C:
        def __init__(self,x=0):
            self.x = x

            
    >>> c1 = C()
    >>> hasattr(c1,'x')    
    #注意,属性名要用引号括起来
    True

     

    getattr(object, name[, default])  返回对象指定的属性值,如果指定的属性不存在,则返回default(可选参数);若没有设置default参数,则抛出异常

    >>> getattr(c1,'x')
    0
    >>> getattr(c1,'y')

    Traceback (most recent call last):
      File "<pyshell#25>", line 1, in <module>
        getattr(c1,'y')
    AttributeError: 'C' object has no attribute 'y'

    setattr(object, name, value)  可以设置对象中指定属性的值,如果指定的属性不存在,则会新建属性并赋值
    >>> setattr(c1,'y','FishC')
    >>> getattr(c1,'y')
    'FishC'

    delattr(object, name)  用于删除对象中指定的属性,如果属性不存在,抛出异常。

    >>> delattr(c1,'y')
    >>> delattr(c1,'Z')

    Traceback (most recent call last):
      File "<pyshell#30>", line 1, in <module>
        delattr(c1,'Z')
    AttributeError: Z

    property(fget=None, fset=None, fdel=None, doc=None)  用来通过属性设置属性,第一个参数是获取属性的方法名,第二个参数是设置属性的方法名,第三个参数是删除属性的方法名

    >>> class C:
        def __init__(self,size =10):
            self.size = size
        def getSize(self):
            return self.size
        def setSize(self,value):
            self.size = value
        def delSize(self):
            del self.size
        x=property(getSize,setSize,delSize)

        

    >>> c = C()
    >>> c.x         #调用getSize()
    10
    >>> c.x = 12      #调用SetSize()
    >>> c.x
    12
    >>> c.size
    12
    >>> del c.x      #调用DelSize()
    >>> c.size
    Traceback (most recent call last):
      File "<pyshell#53>", line 1, in <module>
        c.size
    AttributeError: 'C' object has no attribute 'size'

    041 魔法方法:构造和析构

    __init__(self[, ...]) 方法是类在实例化成对象的时候首先会调用的一个方法

    >>> class Rectangle:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        def getPeri(self):
            return (self.x + self.y) * 2
        def getArea(self):
            return self.x * self.y

    >>> rect = Rectangle(5,2)
    >>> rect.getPeri()
    14
    >>> rect.getArea()
    10

       注:__init__()方法的返回值一定是None 

    其实,__new__()才是在一个对象实例化时候所调用的第一个方法,它的第一个参数是这个类(cla),而其他的参数会直接传递给__init__()方法

    __new__(cls[, ...])

    >>> class CapStr(str):
        def __new__(cls,string):
            string = string.upper()
            return str.__new__(cls,string)

        
    >>> a = CapStr('hello world')
    >>> a
    'HELLO WORLD

    __del__(self)  当对象将要被销毁的时候,这个方法就会被调用。但要注意,并非del x就相当于调用x.__del__(),__del__()方法是当垃圾回收机制回收这个对象的时候才调用的。

    >>> class C:
        def __init__(self):
            print('我是__init__方法,我被调用了...')
        def __del__(self):
            print('我是__del__方法,我被调用l...')

            
    >>> c1 = C()     #创建对象c1
    我是__init__方法,我被调用了...
    >>> c2 = c1
    >>> c3 = c2
    >>> del c1
    >>> del c2
    >>> del c3   #删除c3时,对象c1才会彻底被删除(即没有标签指向对象c1时,其才会被回收)
    我是__del__方法,我被调用l...

    042 魔法方法:算术运算

    python2.2以后,对类和类型进行了统一,做法就是讲int()、float()、str()、list()、tuple()这些BIF转换为工厂函数(类对象):

    >>> type(len)
    <class 'builtin_function_or_method'>            #普通的BIF
    >>> type(int)
    <class 'type'>             #工厂函数(类对象),当调用它们的时候,其实就是创建了一个相应的实例对象
    >>> type(dir)
    <class 'builtin_function_or_method'>
    >>> type(list)
    <class 'type'>

    >>> a = int('123')        #创建一个相应的实例对象a
    >>> b = int('345')
    >>> a + b              #python在两个对象进行相加操作
    468

    举个例子,下面定义一个比较特立独行的类:

    >>> class New_int(int):
        def __add__(self,other):
            return int.__sub__(self,other)
        def __sub__(self,other):
            return int.__add__(self,other)

        
    >>> a = New_int(3)
    >>> b = New_int(5)
    >>> a + b    #两个对象相加,触发 __add__(self,other)方法
    -2
    >>> a - b
    8
    >>>

    实例2:

    >>> class New_int(int):
        def __add__(self,other):
            return (int(self) + int(other))       #将self与other强制转换为整型,所以不会出现两个对象相加触发__add__()方法
        def __sub__(self,other):
            return (int(self) - int(other))

        
    >>> a = New_int(3)
    >>> b = New_int(5)
    >>> a + b
    8

    043 魔法方法:算术运算2

    实例1:

    >>> class int(int):
        def __add__(self,other):
            return int.__sub__(self,other)

        
    >>> a = int(3)
    >>> b = int(2)
    >>> a + b
    1

    反运算:

    反运算与算术运算符的不同之处是,反运算多了一个'r',例如 __add__()的反运算对应为 __radd__()

    >>> a + b

    这里a是加数,b是被加数,如果a对象的__add__()方法没有实现或者不支持相应的操作,那么python就会自动调用b的__radd__()方法

    实例:

    >>> class Nint(int):
        def __radd__(self,other):
            return int.__sub__(self,other)

        
    >>> a = Nint(5)
    >>> b = Nint(3)
    >>> a + b      #由于a对象默认有__add__()方法,所以b的__radd__()没有执行
    8

    实例2:

    >>> class Nint(int):
        def __radd__(self,other):
            return int.__sub__(self,other)

        
    >>> b = Nint(5)
    >>> 3 + b         #由于3无__add__()方法,所以执行b的反运算__radd__(self,other)方法,其中self是b对象
    2

    注:在重写反运算魔法方法时,一定要注意顺序问题。

    增量赋值运算:

    比较操作符:

    其它操作符:

    044 魔法方法:简单定制

    简单定制

    基本要求:

    定制一个计时器的类

    startstop方法代表启动计时和停止计时

    假设计时器对象t1print(t1)和直接调用t1均显示结果

    当计时器未启动或已经停止计时,调用stop方法会给予温馨的提示

    两个计时器对象可以进行相加:t1 + t2

    只能使用提供的有限资源完成

    你需要这些资源

    使用time模块的localtime方法获取时间

    扩展阅读:time 模块详解(时间获取和转换)

    有关time模块的localtime方法获取时间(参考:

    https://fishc.com.cn/forum.php?mod=viewthread&tid=51326&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403

    time.localtime返回struct_time的时间格式

    表现你的类:__str__ __repr__

    实例:

    import time as t   #导入时间模块,调用对象t

    class Mytimer():
        def __init__(self):
            self.unit = ['年','月','天','小时','分钟','秒']
            self.prompt = "未开始计时"
            self.lasted = []
            self.begin = 0  #属性
            self.end = 0
        def __str__(self):
            return self.prompt

        __repr__ = __str__

        def __add__(self,other):   #重写加法操作符,运行时间相加
            prompt = "总共运行了"
            result = []
            for index in range(6):
                result.append(self.lasted[index] + other.lasted[index])
                if result[index]:
                    prompt += (str(result[index]) + self.unit[index])
            return prompt
                               
        #开始计时
        def start(self):    #方法,属性名和方法名不能相同
            if not self.stop:
                self.prompt = ("提示:请先调用stop()停止计时!")
            else:
                self.begin = t.localtime()
                print('计时开始...')

        #停止计时
        def stop(self):
            if not self.begin:
                print('提示:请先调用start()进行计时!')
            else:
                self.end = t.localtime()
                self._calc()
                print('计时结束!')

        #内部方法,计算运行时间
        def _calc(self):
            self.prompt = "总共运行了"
            for index in range(6):
                self.lasted.append(self.end[index] - self.begin[index])
                if self.lasted[index]:
                    self.prompt += (str(self.lasted[index]) + self.unit[index])
            #为下一轮计时初始化变量
            self.begin = 0
            self.end = 0

    >>> t1 = Mytimer()
    >>> t1.stop()
    提示:请先调用start()进行计时!
    >>> t1.start()
    计时开始...
    >>> t1.stop()
    计时结束!
    >>> t1
    总共运行了4秒
    >>> t2 = Mytimer()
    >>> t2.start()
    计时开始...
    >>> t2.stop()
    计时结束!
    >>> t2
    总共运行了4秒
    >>> t1 + t2
    '总共运行了8秒'        

    进阶定制

    如果开始计时的时间是202222216:30:30,停止时间是202512315:30:30,那按照我们用停止时间减开始时间的计算方式就会出现负数3-11-1小时)你应该对此做一些转换

    现在的计算机速度都非常快,而我们这个程序最小的计算单位却只是秒,精度是远远不够的

    045 魔法方法:属性访问

    属性访问

    __getattr__(self, name)

    定义当用户试图获取一个不存在的属性时的行为

    __getattribute__(self, name)

    定义当该类的属性被访问时的行为

    __setattr__(self, name, value)

    定义当一个属性被设置时的行为

    __delattr__(self, name)

    定义当一个属性被删除时的行为

    实例1:

    class C:
        def __getattribute__(self, name):
            print('getattribute')
            # 使用 super() 调用 object 基类的 __getattribute__ 方法
            return super().__getattribute__(name)

        def __setattr__(self, name, value):
            print('setattr')
            super().__setattr__(name, value)

        def __delattr__(self, name):
            print('delattr')
            super().__delattr__(name)

        def __getattr__(self, name):
            print('getattr')

    >>> c = C()
    >>> c.x
    getattribute
    getattr
    >>> c.x = 1
    setattr
    >>> c.x
    getattribute
    1
    >>> del c.x
    delattr
    >>> setattr(c,'y','Yellow')
    setattr

    练习要求

    写一个矩形类,默认宽和高两个属性

    如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时宽和高都应该等于边长。

    实例2:

    class Rectangle:
        def __init__(self, width=0, height=0):
            self.width = width
            self.height = height

        def __setattr__(self, name, value):#一发生赋值操作,则会触发__setattr__()魔法方法
            if name == 'square':#判断name属性是否为正方形
                self.width = value
                self.height = value
            else:
                self.__dict__[name] = value

        def getArea(self):
            return self.width * self.height

    >>> r1 = Rectangle(4,5)
    >>> r1.getArea()
    20
    >>> r1.square = 10
    >>> r1.getArea()
    100

    046 魔法方法:描述符(Property的原理)

    描述符

    描述符就是将某种特殊类型的类的实例指派给另一个类的属性。

    __get__(self, instance, owner)

    用于访问属性,它返回属性的值

    __set__(self, instance, value)

    将在属性分配操作中调用,不返回任何内容

    __delete__(self, instance)

    控制删除操作,不返回任何内容

    实例:

    >>> class MyDecriptor:
        def __get__(self,instance,owner):
            print("getting...",self,instance,owner)
        def __set__(self,instance,value):
            print("setting...",self,instance,value)
        def __delete__(self,instance):
            print("deleting...",self,instance)

     

    >>> class Test:
        x = MyDecriptor()   #取Mydecriptor类的实例指派给Test类的属性x

    >>> test = Test()
    >>> test.x
    getting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98> <class '__main__.Test'>
    >>> test
    <__main__.Test object at 0x000000000335EF98>
    >>> test.x = "X-man"
    setting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98> X-man
    >>> del test.x
    deleting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98>

     

    实例2:

    >>> class MyProperty:
        def __init__(self,fget = None,fset = None,fdel = None):
            self.fget = fget
            self.fset = fset
            self.fdel = fdel
        def __get__(self,instance,owner):
            return self.fget(instance)
        def __set__(self,instance,value):
            self.fset(instance,value)
        def __delete__(self,instance):
            self.fdel(instance)

            
    >>> class C:
        def __init__(self):
            self._x = None
        def getX(self):
            return self._x
        def setX(self,value):
            self._x = value
        def delX(self):
            del self._x
        x = MyProperty(getX,setX,delX)

        
    >>> c = C()
    >>> c.x = "HELLOW"
    >>> c.x
    'HELLOW'
    >>> c._x
    'HELLOW'
    >>> del c.x
    >>> c._x
    Traceback (most recent call last):
      File "<pyshell#70>", line 1, in <module>
        c._x
    AttributeError: 'C' object has no attribute '_x'

    练习要求

    先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性

    要求个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果。

    实例3:

    ss Celsius:  #摄氏度描述符类
        def __init__(self,value = 26.0):#self为描述符类自身(此为摄氏度描述符类)的实例(此为cel)
            self.value = float(value)
        def __get__(self,instance,owner):#instance是这个描述符的拥有者所在的类的实例(此为temp)
            return self.value
        def __set__(self,instance,value):#owner是这个描述符的拥有者所在的类本身(此为温度类)
            self.value = float(value)

    class Fahrenheit:   #华氏度描述符类
        def __get__(self,instance,owner):
            return instance.cel * 1.8 +32  #摄氏度转华氏度
        def __set__(self,instance,value):
            instance.cel = ((float)(value)- 32)/ 1.8   #华氏度转摄氏度
            
    class Temperature:   #温度类
        cel = Celsius()   #设置摄氏度属性(描述符类的实例指派给了温度类的属性)
        fah = Fahrenheit()#设置华氏度属性

    >>> temp = Temperature()
    >>> temp.cel
    26.0
    >>> temp.fah
    78.80000000000001
    >>> temp.fah = 78.8
    >>> temp.cel
    25.999999999999996

    047 魔法方法:定制序列

    协议是什么?

    协议(Protocols)与其他编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在Python中的协议就显得不那么正式。事实上,在Python中,协议更像是一种指南

    容器类型的协议

    如果说你希望定制的容器是不可变的话,你只需要定义__len__()__getitem__()方法。

    如果你希望定制的容器是可变的话,除了__len__()__getitem__()方法,你还需要定义__setitem__()__delitem__()两个方法。

    练习要求

    编写一个不可改变的自定义列表,要求记录列表中每个元素被访问的次数。

    class CountList:  #定义记录列表中每个元素访问次数类
        def __init__(self,*args): #参数是可变类型的
            self.values = [x for x in args]#将args的数据存入列表self.values中
            self.count = {}.fromkeys(range(len(self.values)),0)#创建字典,初试化为0

        def __len__(self):  #返回容器中元素的个数
            return len(self.values)#len方法用于返回参数的长度 
        def __getitem__(self,key):  #获取容器中指定元素的行为,key为访问对应的键
            self.count[key] += 1#每访问一次,字典键对应的键值加1
            return self.values[key]

    >>> c1 = CountList(1,3,5,7,9)
    >>> c2 = CountList(2,4,6,8,10)
    >>> c1[1]  #c1[1]第一次访问
    3
    >>> c2[2]
    6
    >>> c1[1] + c2[2] #c1[1]第二次访问
    9
    >>> c1.count
    {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
    >>> c2.count
    {0: 0, 1: 0, 2: 2, 3: 0, 4: 0}

    048 魔法方法:迭代器

    迭代的意思类似于循环,每一次重复的过程被称为一次迭代的过程,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。提供迭代方法的容器称为迭代器(如序列(列表、元组、字符串)、字典等)。

    对一个容器对象调用iter()就得到它的迭代器,调用next()迭代器就会返回下一个值。入托迭代器没有值可以返回了,就会抛出异常。

    •iter()

    –__iter__()

    •next()

    –__next__()

    实例1:

    >>> string = "FishC"
    >>> it = iter(string)
    >>> next(it)
    'F'
    >>> next(it)
    'i'
    >>> next(it)
    's'
    >>> next(it)
    'h'
    >>> next(it)
    'C'
    >>> next(it)
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        next(it)
    StopIteration

    一个容器如果是迭代器,那就必须实现__iter__()魔法方法,这个方法实际上就是返回迭代器本身。重点要实现的是__next__()魔法方法,因为它决定了迭代的规则。

    实例2:

    >>> class Fibs:
        def __init__(self):
            self.a = 0
            self.b = 1
        def __iter__(self):
            return self
        def __next__(self):
            self.a,self.b = self.b,self.a + self.b
            return self.a

        
    >>> fibs = Fibs()
    >>> for each in fibs:
        if each < 20:
            print(each)
        else:
            break

        
    1
    1
    2
    3
    5
    8
    13

    实例3:

     

    >>> class Fibs:
        def __init__(self,n =20):
            self.a = 0
            self.b = 1
            self.n = n
        def __iter__(self):
            return self
        
        def __next__(self):
            self.a,self.b = self.b,self.a + self.b
            if self.a > self.n:
                raise StopIteration
            return self.a

        
    >>> fibs = Fibs()
    >>> for each in fibs:
        print(each)

        
    1
    1
    2
    3
    5
    8
    13

     

    >>> fibs = Fibs(10)
    >>> for each in fibs:
        print(each)

        
    1
    1
    2
    3
    5
    8

     

    049 乱入:生成器

    所谓协同程序,就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。

    生成器可以暂时挂起函数,并保留函数的局部变量等数据,然后在再次调用它的时候,从上次暂停的位置继续执行下去。

    一个函数中如果有yield语句,则被定义为生成器。

    实例1:

    >>> def myGen():
        print("生成器被执行了!")
        yield 1   #暂停一次,相当于return,返回1
        yield 2     #暂停一次,相当于return,返回2

        
    >>> myG = myGen()
    >>> next(myG)
    生成器被执行了!
    1
    >>> next(myG)
    2

    像前面介绍的斐波那契的例子,也可以用生成器来实现:

    >>> def fibs():
        a = 0
        b = 1
        while True:
            a,b = b,a + b
            yield a

            
    >>> for each in fibs():
        if each > 100:
            break
        print(each)

        
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    89

    列表推导式表达:

    100以内,能被2整除,但不能被3整除的所有整数

    >>> a = [i for i in range(100) if not (i % 2) and (i % 3 )]
    >>> a
    [2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]

    字典推导式:

    10以内是否为偶数

    >>> a = {i:i % 2 == 0 for i in range(10)}
    >>> a
    {0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}

    集合推导式:

    >>> a = {i for i in [1,2,3,3,4,5,5,5,6,7,7,8]}
    >>> a
    {1, 2, 3, 4, 5, 6, 7, 8}

    元组生成器推导式:

    >>> e = (i for i in range(5))
    >>> next(e)
    0
    >>> next(e)
    1
    >>> next(e)
    2

    050 模块:模块就是程序

    什么是模块

    容器 -> 数据封装

    函数 -> 语句封装

    -> 方法和属性的封装

    模块 -> 模块就是程序

    命名空间

    爱的宣言:世界上只有一个名字,使我这样牵肠挂肚,像有一根看不见的线,一头牢牢系在我心尖上,一头攥在你手中,这个名字就叫做鱼C工作室计算机一班的小花……

    导入模块

    第一种:import 模块名

    实例1:import导入模块

    实例2:import导入模块

    第二种:from 模块名 import 函数名(不推荐使用)

    第三种:import 模块名 as 名字(推荐使用)

    TemperatureConversion文件:

    def c2f(cal):
        return cal * 1.8 + 32
    def f2c(fah):
        return (fah - 32)/1.8

    calc文件:

    import TemperatureConversion as tc  #tc为取得新名字

    print("32摄氏度 = %.2f 华氏度\n" % tc.c2f(32))
    print("99华氏度 = %.2f 摄氏度" % tc.f2c(99))

    051 模块:__name__='__main__'、搜索路径和包

    模块!模块!

    实例1:为TemperatureConversion添加测试程序(TemperatureConversion被作为程序运行)

    def c2f(cal):
        return cal * 1.8 + 32

    def f2c(fah):
        return (fah - 32)/1.8

    def test():
        print("0摄氏度 = %.2f 华氏度\n" % c2f(0))
        print("0华氏度 = %.2f 摄氏度" % f2c(0))

    test()

    运行calc文

    当希望TemperatureConversion被调用时作为模块导入时

    def c2f(cal):
        return cal * 1.8 + 32

    def f2c(fah):
        return (fah - 32)/1.8

    def test():
        print("0摄氏度 = %.2f 华氏度" % c2f(0))
        print("0华氏度 = %.2f 摄氏度" % f2c(0))

    if __name__ == "__main__":#当此文件当做程序运行时,执行test(),否则不执行
        test()

    运行calc文件

    if __name__ == ‘__main__’

    搜索路径(系统会首先搜索的路径)

    >>> import sys
    >>> sys.path
    ['D:\\python3.3.2\\小甲鱼python\\python程序\\第五十节课\\Temperature', 'D:\\python3.3.2\\Lib\\idlelib', 'C:\\windows\\system32\\python33.zip', 'D:\\python3.3.2\\DLLs', 'D:\\python3.3.2\\lib', 'D:\\python3.3.2', 'D:\\python3.3.2\\lib\\site-packages']

    添加搜索路径:

    >>> import TemperatureConversion
    Traceback (most recent call last):
      File "<pyshell#0>", line 1, in <module>
        import TemperatureConversion
    ImportError: No module named 'TemperatureConversion'

    >>> import sys
    >>> sys.path.append("D:\\python3.3.2\WODE\Temperature")
    >>> sys.path
    ['', 'D:\\python3.3.2\\Lib\\idlelib', 'C:\\windows\\system32\\python33.zip', 'D:\\python3.3.2\\DLLs', 'D:\\python3.3.2\\lib', 'D:\\python3.3.2', 'D:\\python3.3.2\\lib\\site-packages', 'D:\\python3.3.2\\WODE\\Temperature']
    >>> import TemperatureConversion
    >>> TemperatureConversion.f2c(59)
    15.0

    package

    1.创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字;

    2.文件夹中创建一个__init__.py的模块文件,内容可以为空;

    3.相关的模块放入文件夹中

    052 模块:像个极客一样去思考

    使用print调用__doc__属性,可以带格式查看这个模块的简介

    使用dir()可以查询到该模块定义了哪些变量、函数和类

    053 论一只爬虫的自我修养

    Python如何访问互联网?

     

    URL的一般格式为(带方括号[]的为可选项)

    protocol :// hostname[:port] / path / [;parameters][?query]#fragment

    URL由三部分组成:

    第一部分是协议httphttpsftpfileed2k…

    第二部分是存放资源的服务器的域名系统或IP地址(有时候要包含端口号,各种传输协议都有默认的端口号,如http的默认端口为80)。

    第三部分是资源的具体地址,如目录文件名

    054 论一只爬虫的自我修养2:实战

    import urllib.request

    response = urllib.request.urlopen('http://placekitten.com/g/500/600')#  返回文件对象response
    cat_imag = response.read()

    with open('cat_500_600.jpg','wb') as f:
        f.write(cat_imag)

    >>> response.geturl()
    'http://placekitten.com/g/500/600'
    >>> response.info()
    <http.client.HTTPMessage object at 0x00000000034EAA20>
    >>> print(response.info())
    Date: Sat, 27 Jul 2019 02:44:18 GMT
    Content-Type: image/jpeg
    Transfer-Encoding: chunked
    Connection: close
    Set-Cookie: __cfduid=d3cd08233581619b9ef8464ae93f7d5ff1564195458; expires=Sun, 26-Jul-20 02:44:18 GMT; path=/; domain=.placekitten.com; HttpOnly
    Access-Control-Allow-Origin: *
    Cache-Control: public, max-age=86400
    Expires: Sun, 28 Jul 2019 02:44:18 GMT
    CF-Cache-Status: HIT
    Age: 66459
    Vary: Accept-Encoding
    Server: cloudflare
    CF-RAY: 4fcb454ecc35ce6b-LHR


    >>> response.getcode()
    200

    055 论一只爬虫的自我修养3:隐藏

    修改 headers

    通过Requestheaders参数修改

    通过Request.add_header()方法修改

    代理

    步骤:

    1. 参数是一个字典 {‘类型’:‘代理ip:端口号’}

    proxy_support = urllib.request.ProxyHandler({})

     

    2. 定制、创建一个 opener

    opener = urllib.request.build_opener(proxy_support)

     

    3a. 安装 opener

    urllib.request.install_opener(opener)

    3b. 调用 opener

    opener.open(url)

     

    064 GUI的终极选择:Tkinter

     

    >>> import tkinter   #Tkinter是python默认的GUI库,导入Tkinter模块
    >>> 

    实例1:

    import tkinter as tk

    root = tk.Tk()#创建一个主窗口,用于容纳整个GUI程序
    root.title("FishC Demo")#设置主窗口对象的标题栏

    #添加一个Label组件,可以显示文本、图标或者图片(此处显示文本)
    theLabel = tk.Label(root,text = "我的第二个窗口程序")
    theLabel.pack()#调用Label组件的pack方法,用于自动调节组件自身尺寸

    root.mainloop()#执行此语句后,窗口才会显示,程序进入主事件循环

    实例2:

    import tkinter as tk

    class App:#创建类App
        def __init__(self,root):#self为指向App类的指针
            #创建一个框架,然后在里面添加一个Button按钮组件,框架用来将复杂布局中按钮分组
            frame = tk.Frame(root)
            frame.pack(side = tk.RIGHT,padx = 10,pady = 10)#调节框架自身尺寸,此处设置为右对齐(右上角为原点),偏移(10,10)
            
            #创建一个按钮组件,fg(foreground),设置前景色
            #创建一个Button按钮,属性为self.hi_there,属于frame框架,按钮按下时调用self.say_hi方法
            #设置前景色为黑色,背景色为白色
            self.hi_there = tk.Button(frame,text = "打招呼",bg = "black",fg = "white",command = self.say_hi)
            self.hi_there.pack()#自动调节自身尺寸
            
            #say_hi()方法定义实现   
        def say_hi(self):
            print("互联网广大朋友们好,我是亦我飞也!")
            
            
    root = tk.Tk()#创建一个主窗口(toplever的根窗口),并把它作为参数实例化app对象,用于容纳整个GUI程序,
    app = App(root)#创建类App的一个实例对象app,传入参数为root

    app.mainloop()#执行此语句后,窗口才会显示,程序进入主事件循环
     

    065 GUI的终极选择:Tkinter2

    实例1:Label组件显示文字与gif图片

    #导入tkinter模块的所有内容
    from tkinter import *

    #创建主窗口
    root = Tk()
    #创建一个文本Label对象,文字为左对齐,离左边边框距离为10
    textLabel = Label(root,
                      text = "您下载的影片含有未成年人限制内容,\n请满18周岁后再点击观看!",
                      justify = LEFT,padx = 10)
    #Label组件为左对齐
    textLabel.pack(side = LEFT)

    #创建一个图像Label对象
    #用PhotoImage实例化一个图片对象(支持gif格式的图片)
    photo = PhotoImage(file = "18.gif")
    imgLabel = Label(root,image = photo)
    imgLabel.pack(side = RIGHT)

    mainloop()
     

    实例2:

    例2:文字显示在图片上

    #导入tkinter模块的所有内容
    from tkinter import *

    #创建主窗口
    root = Tk()

    #创建一个图像Label对象
    photo = PhotoImage(file = "bg.gif")
    #创建一个文本Label对象
    textLabel = Label(root,
                      text = "学Python\n到FishC!",
                      font = ("宋体",20),
                      fg = "white",
                      justify = LEFT,  #文字左对齐
                      image = photo,
                      compound = CENTER, #设置文本和图像的混合模式
                      )
    #文本Label对象偏移,离左窗口与上窗口都为10
    textLabel.pack(side = LEFT,padx =10,pady =10)

    mainloop()
     

    实例2:Button组件

    #导入tkinter模块的所有内容
    from tkinter import *

    def callback():
        var.set("吹吧你,我才不信呢~")

    #创建主窗口
    root = Tk()
    #设置主窗口对象的标题栏
    root.title("TK")

    frame1 = Frame(root)#框架1
    frame2 = Frame(root)#框架2

    #创建一个文本Label对象,文字为左对齐
    var = StringVar()
    var.set("您下载的影片含有未成年人限制内容,\n请满18周岁后再点击观看!")
    textLabel = Label(frame1,
                      textvariable = var, #Button显示一个StringVar的变量
                      justify = LEFT)
    #Label组件为左对齐
    textLabel.pack(side = LEFT)

    #创建一个图像Label对象
    #用PhotoImage实例化一个图片对象(支持gif格式的图片)
    photo = PhotoImage(file = "18.gif")
    imgLabel = Label(root,image = photo)
    imgLabel.pack(side = RIGHT)

    #加一个按钮
    theButton = Button(frame2,text = "已满18周岁",command = callback)
    theButton.pack()
    frame1.pack(padx = 10,pady = 10)
    frame2.pack(padx = 10,pady = 10)

    mainloop()

    066 GUI的终极选择:Tkinter3

    实例1:Checkbutton 组件

    from tkinter import *

    root = Tk()
    #需要一个Tkinter变量,用于表示该按钮是否被选中
    v = IntVar()
    c = Checkbutton(root,text="测试一下",variable = v)

    c.pack()
    #如果被选中,那么变量v被赋值为1,否则为0
    #可以用个Label标签动态地给大家展示:
    lable = Label(root,textvariable = v)
    lable.pack()

    mainloop()

    实例2:

    from tkinter import *

    root = Tk()

    GIRLS = ["貂蝉","王昭君","西施","杨玉环"]
    v = []
    for girl in GIRLS:
        v.append(girl)
        c = Checkbutton(root,text = girl,variable = v[-1])#-1表示每次取v列表中最后一个元素,即刚加入的那个元素
        c.pack(anchor = W)#W(western)向左对齐

    mainloop()

    实例3:Radiobutton 组件

    from tkinter import *

    root = Tk()

    v = IntVar()#如果被选中,v被赋值为1,否则为0
    Radiobutton(root,text = "One",variable = v,value = 1).pack(anchor = W)
    #value表示第一个按钮被选中时,v的值赋值给variable

    Radiobutton(root,text = "Two",variable = v,value = 2).pack(anchor = W)

    Radiobutton(root,text = "Three",variable = v,value = 3).pack(anchor = W)

    Radiobutton(root,text = "Four",variable = v,value = 4).pack(anchor = W)

    mainloop()

    实例4:循环处理

    from tkinter import *

    root = Tk()

    LANGS = [
        ("Python",1),
        ("Perl",2),
        ("Ruby",3),
        ("Lua",4)]
         

    v = IntVar()#如果被选中,v被赋值为1,否则为0
    v.set(1)#将1设置为默认值
    for lang,num in LANGS:
        b= Radiobutton(root,text = lang,variable = v,value = num)
        b.pack(anchor = W)
    #value表示第一个按钮被选中时,v的值赋值给variable

    mainloop()

    实例5:改成按钮形式

    from tkinter import *

    root = Tk()

    LANGS = [
        ("Python",1),
        ("Perl",2),
        ("Ruby",3),
        ("Lua",4)]
         

    v = IntVar()#如果被选中,v被赋值为1,否则为0
    v.set(1)#将1设置为默认值
    for lang,num in LANGS:
        b= Radiobutton(root,text = lang,variable = v,value = num,indicatoron = False)
        b.pack(fill = X)#表示横向填充
    #value表示第一个按钮被选中时,v的值赋值给variable

    mainloop()

    实例6:LabelFrame 组件

    from tkinter import *

    root = Tk()

    group = LabelFrame(root,text = "最好的脚本语言是?",padx = 10,pady = 10)#按钮相对边框的偏移
    group.pack(padx = 10,pady = 10)#框架相对边框的偏移

    LANGS = [
        ("Python",1),
        ("Perl",2),
        ("Ruby",3),
        ("Lua",4)]
         

    v = IntVar()#如果被选中,v被赋值为1,否则为0
    v.set(1)#将1设置为默认值
    for lang,num in LANGS:
        b= Radiobutton(group,text = lang,variable = v,value = num,indicatoron = False)
        b.pack(fill = X)
    #value表示第一个按钮被选中时,v的值赋值给variable

    mainloop()

    067 GUI的终极选择:Tkinter4

    实例1:

    from tkinter import *

    root = Tk()#创建主窗口
    e = Entry(root)#在主窗口中插入输入框
    e.pack(padx = 20,pady = 20)

    e.delete(0,END)#清空输入框
    e.insert(0,"默认文本...")#设置输入框内容

    mainloop()

    实例2:

    from tkinter import *

    def button1_show():
        print("作品:《%s》" % e1.get())#将e1.get()中得到的输入框1的内容格式化为字符串
        print("作者:%s" % e2.get())

    root = Tk()#创建主窗口

    Label(root,text = "作品:",padx = 20,pady = 10).grid(row=0,column=0)#第1行第1列,偏移是相对于当前操作组件的相邻x轴或y轴的偏移距离
    Label(root,text = "小甲鱼:").grid(row=1,column=0)#第1行第0列


    e1 = Entry(root)#在主窗口中插入输入框,文本框的内容通过e1调用
    e2 = Entry(root)#在主窗口中插入输入框
    e1.grid(row=0,column=1,padx=10)#x方向偏移是相对于"作品"的x方向偏移的;y方向偏移表示此输入框与y方向相邻物体或边框之间偏移的距离(y方向偏移)
    e2.grid(row=1,column=1,padx=10,pady=20)#x方向偏移是相对于"小甲鱼"的x方向偏移的;y方向偏移表示此输入框与y方向相邻上下物体或边框偏移的距离(y方向偏移)


    #加两个按钮
    Button1 = Button(root,text = "获取信息",command = button1_show)\
              .grid(row = 2,column = 0,sticky = W,padx = 10,pady=10)#加入反斜杠可实现分行编辑,方位设置为最西边(即靠左)
    Button2 = Button(root,text = "退出",command = root.quit).grid(row = 2,column = 1,sticky = E,padx=10)#方位设置为最东边(即靠右)

    #注:双击打开文件时退出才有效
    e1.delete(0,END)#清空输入框
    e1.insert(0,"零基础入门学习Python")#设置输入框内容

    e2.delete(1,END)#清空输入框
    e2.insert(1,"小甲鱼")#设置输入框内容

    mainloop()

    按下获取信息

    更改输入框数据,然后按下获取信息

    实例2:账号密码设置

    from tkinter import *

    def show():
        print("作品:《%s》" % e1.get())#将e1.get()中得到的输入框1的内容格式化为字符串
        print("作者:%s" % e2.get())
        e1.delete(0,END)#清空输入框1
        e2.delete(0,END)#清空输入框2

    root = Tk()#创建主窗口
    #Tkinter总共提供了三种布局组件的方法:pack()、grid()和place()
    #grid()方法允许你用表格的形式来管理组件的位置
    #row选项代表行,coulumn选项代表列
    #row = 1,column = 2表示第二行第三列(0表示第一行)

    Label(root,text = "账号:").grid(row=0)#第1行
    Label(root,text = "密码:").grid(row=1)#第2行
    v1 = StringVar()
    v2 = StringVar()

    e1 = Entry(root,textvariable = v1)#在主窗口中插入输入框,文本框的内容通过e1调用
    e2 = Entry(root,textvariable = v2,show="*")#在主窗口中插入输入框
    e1.grid(row=0,column=1,padx=10,pady=5)#x方向偏移是相对于"作品"的x方向偏移的;y方向偏移表示此输入框与y方向相邻物体或边框之间偏移的距离(y方向偏移)
    e2.grid(row=1,column=1,padx=10,pady=5)#x方向偏移是相对于"小甲鱼"的x方向偏移的;y方向偏移表示此输入框与y方向相邻上下物体或边框偏移的距离(y方向偏移)


    #可以使用sticky选项来设置组件的位置
    #使用N、E、S、W以及他们的组合NE、SE、SW、NW来表示方位

    #加两个按钮
    Button(root,text = "芝麻开门",command = show)\
              .grid(row = 2,column = 0,sticky = W,padx = 10,pady=5)#加入反斜杠可实现分行编辑,方位设置为最西边(即靠左)
    Button(root,text = "退出",command = root.quit).grid(row = 2,column = 1,sticky = E,padx=10)#方位设置为最东边(即靠右)

    mainloop()

    实例3:验证函数validatecommand

    from tkinter import *

    master = Tk()

    def test():
        if e1.get() == "小甲鱼":
            print("正确!")
            return True
        else:
            print("错误!")
            e1.delete(0, END)
            return False

    v = StringVar()

    #focusout表示Entry组件失去焦点的时候验证,调用validatecommand的test函数

    e1 = Entry(master, textvariable=v, validate="focusout", validatecommand=test)
    e2 = Entry(master)
    e1.pack(padx=10, pady=10)
    e2.pack(padx=10, pady=10)

    mainloop()
     

    实例4:invalidcommand函数

    from tkinter import *

    master = Tk()

    def test():
        if e1.get() == "小甲鱼":
            print("正确!")
            return True
        else:
            print("错误!")
            e1.delete(0, END)
            return False

    def test2():
        print("我被调用了...")

    v = StringVar()

    #focusout表示Entry组件失去焦点的时候验证,调用validatecommand的test函数
    #invalidcommand选项指定的函数只有在validatecommand的返回值为False的时候才被调用
    e1 = Entry(master, textvariable=v, validate="focusout", validatecommand=test,\
               invalidcommand=test2)
    e2 = Entry(master)
    e1.pack(padx=10, pady=10)
    e2.pack(padx=10, pady=10)

    mainloop()
     

    实例5:验证函数提供一些额外的选项

    validatecommand(f,s1,s2,...)

    其中,f是验证函数名,s1,s2,s3是额外的选项,这些选项会作为参数一次传给f函数。在此之前,需要调用register()方法将验证函数包装起来。

    from tkinter import *

    master = Tk()

    v = StringVar()

    def test(content, reason, name):
        if content == "小甲鱼":
            print("正确!")
            print(content, reason, name)
            return True
        else:
            print("错误!")
            print(content, reason, name)
            return False

    testCMD = master.register(test)
    e1 = Entry(master, textvariable=v, validate="focusout", \
               validat
               ecommand=(testCMD, '%P', '%v', '%W'))
    e2 = Entry(master)
    e1.pack(padx=10, pady=10)
    e2.pack(padx=10, pady=10)

    mainloop()
     

    实例6:设计一个 计算器

    from tkinter import *
    #计算函数
    def calc():
        result = int(v1.get())+int(v2.get())#强制转换为整型
        v3.set(result)#将result中的内容放到v3中

    #创建窗口
    root = Tk()
    #创建窗口中的一个frame框架
    frame = Frame(root)
    #设置框架位置并显示
    frame.pack(padx = 10,pady = 10)

    v1 = StringVar()
    v2 = StringVar()
    v3 = StringVar()

    #注意,这里不能使用e1.get()或者v1.get()来获取输入的内容,因为validate选项
    #指定为“key"的时候,有任何输入操作都会被拦截到这个函数中
    #也就是说先拦截,只有这个函数返回True,那么输入的内容才会到变量里去
    #所以要用%P来获取最新的输入框内容
    def test(content):
        if content.isdigit():
            return True
        else:
            return False

    #创建三个Entry组件
    testCMD = frame.register(test)
    #创建2个输入组件,输入的数据赋值给v1、v2
    e1 = Entry(frame, textvariable=v1,width=10, validate="key",\
               validatecommand=(testCMD, '%P'))
    e2 = Entry(frame, textvariable=v2,width=10, validate="key",\
               validatecommand=(testCMD, '%P'))
    #一个输出组件,设置为只读模式(readonly),v3的数据赋值给textvariable进行输出显示
    e3 = Entry(frame, textvariable=v3,width=10, validate="key",\
               validatecommand=(testCMD, '%P'),state="readonly")
    #位置设置
    e1.grid(row=0,column=0,padx=10,pady=10)
    e2.grid(row=0,column=2,padx=10)
    e3.grid(row=0,column=4,padx=10)

    #创建两个Label组件
    Label(frame,text="+").grid(row=0,column=1)
    Label(frame,text="=").grid(row=0,column=3)

    #创建一个按钮,宽度为10
    button=Button(frame,text="计算结果",width=10,command=calc)
    button.grid(row=1,column=2,pady=10)

    mainloop()

    068 GUI的终极选择:Tkinter5

    Listbox组件

    如果需要提供选项给用户选择,单选可以用Radiobutton组件,多选可以用Checkbutton,如果提供的选项非常多,可以考虑使用Listbox组件。Listbox是以列表的形式显示出来,并支持滚动条操作。

    实例1:

    from tkinter import *

    root = Tk()#创建主窗口

    theLB = Listbox(root,setgrid = True,selectmode=EXTENDED)#创建一个空列表
    theLB.pack()

    #往列表里添加数据
    for item in ["鸡蛋","鸭蛋","鹅蛋","李狗蛋"]:
        theLB.insert(END,item)#每次在列表最后插入一个数据

    #创建一个按钮,ACTIVE表示当前选中的数据
    theButton = Button(root,text="删除",command = lambda x = theLB:x.delete(ACTIVE))
    theButton.pack()

    #theLB.delete(0,END)删除所有列表数据

    mainloop()

    注:listbox.delete(0,END)可以删除列表中所有项目

    实例2:添加height选项

    from tkinter import *

    root = Tk()#创建主窗口

    #height=11表示可以显示11个项目
    theLB = Listbox(root,setgrid = True,\
                    selectmode=BROWSE,height=11)#创建一个空列表,选择模式为单选
    theLB.pack()

    #往列表里添加数据
    for item in range(11):
        theLB.insert(END,item)#每次在列表最后插入一个数据

    #创建一个按钮,ACTIVE表示当前选中的数据
    theButton = Button(root,text="删除",command = lambda x = theLB:x.delete(ACTIVE))
    theButton.pack()

    #theLB.delete(0,END)删除所有列表数据

    mainloop()

    Scrollbar组件

    实例1:

    from tkinter import *

    root = Tk()#创建主窗口

    sb = Scrollbar(root)
    sb.pack(side=RIGHT,fill=Y)

    lb = Listbox(root,yscrollcommand=sb.set)#创建一个空列表
    for i in range(1000):
        lb.insert(END,i)
    lb.pack(side=LEFT,fill=BOTH)

    sb.config(command = lb.yview)

    mainloop()

    事实上,这是一个互联互通的过程。当用户操作滚动条时,滚动条响应滚动并同时通过Listbox组件的yview()方法滚动列表框里的内容;同样,当列表框中可视范围发生改变的时候,Listbox组件通过调用Scrollbar组件的set()方法设置滚动条的最新位置。

    Scale组件

    Scale组件主要是通过滑块来表示某个范围内的一个数字,可以通过修改选项设置范围以及分辨率(精度)

    实例1:

    from tkinter import *

    root = Tk()#创建主窗口
    Scale(root,from_=0,to=42).pack()#创建铅锤方向滚动条
    Scale(root,from_=0,to=200,orient=HORIZONTAL).pack()#创建水平方向滚动条

    mainloop()

    实例2:打印当前位置

    from tkinter import *

    def show():
        print(s1.get(),s2.get())#使用get()方法获取当前滑块的位置

    root = Tk()#创建主窗口
    s1 = Scale(root,from_=0,to=42)#创建铅锤方向滚动条
    s1.pack()
    s2 = Scale(root,from_=0,to=200,orient=HORIZONTAL)#创建水平方向滚动条
    s2.pack()

    #创建一个按钮
    Button(root,text="获取位置",command=show).pack()

    mainloop()

    实例3:通过resolution选项控制分辨率(步长),通过tickinterval选项设置刻度

    from tkinter import *

    def show():
        print(s1.get(),s2.get())#使用get()方法获取当前滑块的位置

    root = Tk()#创建主窗口
    #tickinterval表示设置刻度,即每隔多少显示一个刻度
    #length表示滚动条的长度所占的像素数
    #resolution用来控制分辨率(步长)
    s1 = Scale(root,from_=0,to=42,tickinterval=5,length=200,\
               resolution=5,orient=VERTICAL)#创建铅锤方向滚动条
    s1.pack()
    s2 = Scale(root,from_=0,to=200,tickinterval=10,\
               length=600,orient=HORIZONTAL)#创建水平方向滚动条
    s2.pack()

    #创建一个按钮
    Button(root,text="获取位置",command=show).pack()

    mainloop()

    069 GUI的终极选择:Tkinter6

    Text组件

    Text(文本)组件用于显示和处理多种任务。虽然该组件的主要目的是显示多行文本,但它常常也被用于作为简单的文本编辑器和网页浏览器使用。

    实例1:插入内容

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=2)
    text.pack()
    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love\n")#光标当前的位置插入

    #END,对应Text组件的文本缓存区最后一个字符的下一个位置
    text.insert(END,"FishC.com!")

    mainloop()

    实例2:插入image对象windows组件

    from tkinter import *

    def show():
        print("哟,我被点了一下~")

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入

    #创建一个按钮
    b1=Button(root,text="点我点我",command=show)
    text.window_create(INSERT,window=b1)

    mainloop()
     

    实例3:单击按钮显示一张图片

    from tkinter import *

    def show():
        text.image_create(INSERT,image=photo)

    root = Tk()
    text = Text(root,width=30,height=50)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入

    photo = PhotoImage(file='fishc.gif')

    #创建一个按钮
    b1=Button(root,text="点我点我",command=show)
    text.window_create(INSERT,window=b1)

    mainloop()

    Indexer用法

    实例1:“line.column”

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    print(text.get(1.2,1.6))#获取第一行第2列到第一行第六列的数据

    mainloop()

    实例2:“line.end”

    行号加上字符串".end"格式表示为该行最后一个字符的位置

    实例:

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    print(text.get("1.2","1.end"))#获取第一行第2列到第一行第六列的数据

    mainloop()

    Mask用法

    mask(标记)通常是嵌入到Text组件文本中的不可见对象。事实上,Marks是指定字符间的位置,并跟随相应的字符一起移动。

    实例:Mark事实上就是索引,用于表示位置

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.mark_set("here","1.2")#设置光标位置为1.2
    text.insert("here","插")

    mainloop()

    实例2:如果Mark前面的内容发生改变,Mark的位置也会跟着移动

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.mark_set("here","1.2")#设置当前光标位置为1.2
    text.insert("here","插")#执行后当前光标位置(Mark位置)变成了1.3
    text.insert("here","入")
    #text.insert("1.3","入")

    mainloop()

    实例3:如果Mark周围的文本被删除了,Mark仍然存在

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.mark_set("here","1.2")#设置当前光标位置为1.2
    text.insert("here","插")#执行后当前光标位置变成了1.3
    text.delete("1.0",END)
    text.insert("here","入")#here表示当前Mark的位置,如果Mark左边并没有数据则会插入到最左边

    mainloop()

    例4:只有mark_unset()方法可以解除Mark的封印

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.mark_set("here","1.2")#设置当前光标位置为1.2
    text.insert("here","插")#执行后当前光标位置变成了1.3
    text.mark_unset("here")

    text.delete("1.0",END)
    text.insert("here","入")#here表示当前Mark的位置

    mainloop()

    默认插入内容是插入到Mark左侧(就是说插入一个字符后,Mark向后移动了一个字符的位置)

    实例5:插入内容到Mark的右侧

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.mark_set("here","1.2")#设置当前Mark位置为1.2
    text.mark_gravity("here",LEFT)

    text.insert("here","插")#执行后当前Mark位置变成了1.3
    text.insert("here","入")#here表示当前Mark的位置

    mainloop()

    070 GUI的终极选择:Tkinter7

    实例1:添加Tags

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.tag_add("tag1","1.7","1.12","1.14")#1.7(第一行第八列)到1.12,,与1.14设置Tag样式
    text.tag_config("tag1",background ="yellow",foreground="red")

    mainloop()

    实例2:Tags覆盖

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.tag_add("tag1","1.7","1.12","1.14")#1.7(第一行第八列)到1.12,,与1.14设置Tag样式
    text.tag_add("tag2","1.7","1.12","1.14")#1.7(第一行第八列)到1.12,,与1.14设置Tag样式

    text.tag_config("tag1",background ="yellow",foreground="red")
    text.tag_config("tag2",background ="blue")

    mainloop()
     

    实例2:降低Tag优先级

    from tkinter import *

    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.tag_add("tag1","1.7","1.12","1.14")#1.7(第一行第八列)到1.12,,与1.14设置Tag样式
    text.tag_add("tag2","1.7","1.12","1.14")#1.7(第一行第八列)到1.12,,与1.14设置Tag样式

    text.tag_config("tag1",background ="yellow",foreground="red")
    text.tag_config("tag2",background ="blue")

    text.tag_lower("tag2")#降低tag2的优先级

    mainloop()

    实例3:Tags事件绑定

    from tkinter import *
    import webbrowser#导入网页模块

    def show_hand_cursor(event):
        text.config(cursor="arrow")

    def show_arrow_cursor(event):
        text.config(cursor="xterm")

    def click(event):
        webbrowser.open("http://www.fishc.com")
        
    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    text.tag_add("link","1.7","1.16")#1.7(第一行第八列)到1.16
    #设置蓝色前景色并底部划线
    text.tag_config("link",foreground="blue",underline=True)

    #当进入绑定文本段时,鼠标样式切换为“arrow"形态
    text.tag_bind("link","<Enter>",show_hand_cursor)
    #当离开绑定文本段时,鼠标样式切换为“xterm"形态
    text.tag_bind("link","<Leave>",show_arrow_cursor)
    #当触发鼠标“左键单击”时,使用默认浏览器打开鱼C网址
    text.tag_bind("link","<Button-1>",click)

    mainloop()

    实例4:判断内容是否发生改变

    from tkinter import *
    import hashlib

    def getSig(contents):
        m = hashlib.md5(contents.encode())
        return m.digest()

    def check():#检查
        contents = text.get(1.0,END)
        if sig!=getSig(contents):
            print("警报,内容发生变动")
        else:
            print("风平浪静")
        
    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入
    #注意,行号从1开始,列号则从0开始
    #获取文本内容
    contents=text.get(1.0,END)

    sig = getSig(contents)

    Button(root,text="检查",command=check).pack()

    mainloop()

    实例5:查找操作(使用search()方法可以搜索Text组件中的内容)

    from tkinter import *
    import hashlib

    #将任何格式的索引号统一为元组(行,列)的格式输出
    def getIndex(text,index):
        #split这里以"."拆分字符串,将1.3拆分为字符1和3,然后通过map将字符转换为整型
        return tuple(map(int,str.split(text.index(index),".")))
        
    root = Tk()
    text = Text(root,width=30,height=5)
    text.pack()

    #INSERT索引表示插入光标当前的位置
    text.insert(INSERT,"I love FishC.com!")#光标当前的位置插入

    #将任何格式的索引号统一为元组(行、列)的格式输出
    start = 1.0
    while True:
        pos = text.search("o",start,stopindex=END)#从开始到结束全文搜索
        if not pos:
            break
        print("找到了,位置是:",getIndex(text,pos))
        start = pos + "+1c"#将start指向找到的字符位置的下一个字符,以便进行下一次搜索

    mainloop()

    Text组件内部有一个栈专门用于记录内容的每次变动,所以每次“撤销”操作就是一次弹栈操作,“恢复”就是再次压栈。

    实例6:撤销

    from tkinter import *

    #将任何格式的索引号统一为元组(行,列)的格式输出
    def show():
        text.edit_undo()
        
    root = Tk()
    text = Text(root,width=30,height=5,undo=True)
    text.pack()
    text.insert(INSERT,"I love FishC")

    Button(root,text="撤销",command=show).pack()

    mainloop()


    实例7:每次撤销一个字符

    from tkinter import *

    def callback(event):
        text.edit_separator()

    def show():
        text.edit_undo()#执行撤回操作
        
    root = Tk()

    #autoseparators表示一次完整的操作结束后自动插入“分隔符”,此处设置为False
    text = Text(root,width=30,height=5,autoseparators=False,undo=True,maxundo=10)
    text.pack()

    text.insert(INSERT,"I love FishC!")
    text.bind('<Key>',callback)#每次有输入就插入一个“分隔符”

    Button(root,text="撤销",command=show).pack()

    mainloop()

    071 GUI的终极选择:Tkinter8

    Canvas(画布)组件

    一个可以让你随心所欲绘制界面的组件。通常用于显示和编辑图形,可以用它来绘制直线、图形、多边形,甚至是绘制其他组件。

    实例1:

    from tkinter import *
    root = Tk()
    #创建canvas对象框,设置其宽度、高度与背景色
    w = Canvas(root,width=200,height=100,background="black")
    w.pack()

    #画一条黄色的线
    w.create_line(0,50,200,50,fill="yellow")
    #画一条红色的竖线(虚线)
    w.create_line(100,0,100,100,fill="red")
    #中间画一个蓝色的矩形
    w.create_rectangle(50,25,150,75,fill="blue")

    mainloop()

    实例2:

    from tkinter import *
    root = Tk()
    #创建canvas对象框,设置其宽度、高度与背景色
    w = Canvas(root,width=200,height=100,background="black")
    w.pack()

    #画一条黄色的线(参数为其x、y轴坐标)
    line1 = w.create_line(0,50,200,50,fill="yellow")
    #画一条红色的竖线(虚线)
    line2 = w.create_line(100,0,100,100,fill="red")
    #中间画一个蓝色的矩形
    rect1 = w.create_rectangle(50,25,150,75,fill="blue")

    w.coords(line1,0,25,200,25)#将line1移动到新的坐标
    w.itemconfig(rect1,fill="red")#重新设置矩形的填充色为红色
    w.delete(line2)#删除线2

    #创建一个按钮,按下时删除所有图形
    Button(root,text="删除全部",command=(lambda x=ALL:w.delete(x))).pack()

    mainloop()

    实例3:在Canvas上显示文本

    from tkinter import *
    root = Tk()
    #创建canvas对象框,设置其宽度、高度与背景色
    w = Canvas(root,width=200,height=100,background="black")
    w.pack()

    #画一条绿色的斜线(参数为其x、y轴坐标),宽度为三个像素点
    line1 = w.create_line(0,0,200,100,fill="green",width=3)
    #画一条绿色的斜线
    line2 = w.create_line(200,0,0,100,fill="green",width=3)
    #中间画两个矩形
    rect1 = w.create_rectangle(40,20,160,80,fill="blue")
    rect2 = w.create_rectangle(60,30,140,70,fill="yellow")
    #在矩形正中(默认)显示文本,坐标为文本正中坐标
    w.create_text(100,50,text="Hadley")

    #创建一个按钮,按下时删除所有图形
    Button(root,text="删除全部",command=(lambda x=ALL:w.delete(x))).pack()

    mainloop()

    实例4:绘制椭圆

    from tkinter import *
    root = Tk()
    #创建canvas对象框,设置其宽度、高度与背景色
    w = Canvas(root,width=200,height=100,background="white")
    w.pack()

    #绘制一个虚线的矩形
    w.create_rectangle(40,20,160,80,dash=(4,4))
    #绘制椭圆,粉色填充
    w.create_oval(40,20,160,80,fill="pink")
    #在矩形正中(默认)显示文本,坐标为文本正中坐标
    w.create_text(100,50,text="Hadley")

    mainloop()
    实例5:绘制圆形

    from tkinter import *
    root = Tk()
    #创建canvas对象框,设置其宽度、高度与背景色
    w = Canvas(root,width=200,height=100,background="white")
    w.pack()

    #绘制一个虚线的矩形
    w.create_rectangle(40,20,160,80,dash=(4,4))
    #绘制圆形,粉色填充
    #w.create_oval(40,20,160,80,fill="pink")
    w.create_oval(70,20,130,80,fill="pink")
    #在矩形正中(默认)显示文本,坐标为文本正中坐标
    w.create_text(100,50,text="Hadley")

    mainloop()

    实例6:绘制多边形

    from tkinter import *
    import math as m

    root = Tk()
    w=Canvas(root,width=200,height=150,background="red")
    w.pack()
    center_x = 100
    center_y = 80
    r = 70
    points = [
        #左上角A
        center_x - int(r*m.sin(2*m.pi/5)),
        center_y - int(r*m.cos(2*m.pi/5)),
        #右上角C
        center_x + int(r*m.sin(2*m.pi/5)),
        center_y - int(r*m.cos(2*m.pi/5)),
        #左下角E
        center_x - int(r*m.sin(m.pi/5)),
        center_y + int(r*m.cos(m.pi/5)),
        #顶点D
        center_x,
        center_y - r,
        #右下角B
        center_x + int(r*m.sin(m.pi/5)),
        center_y + int(r*m.cos(m.pi/5)),
        ]
    #创建多边形方法,会自动按ACEDBA的形式连线,如果构成闭环,则会自动填充
    w.create_polygon(points,outline="green",fill="yellow")

    w.create_text(100,80,text="Hadley")

    mainloop()

    实例7:

    from tkinter import *

    root = Tk()
    w=Canvas(root,width=400,height=200,background="white")
    w.pack()

    def paint(event):#画小圆
        x1,y1 = (event.x - 1),(event.y -1)
        x2,y2 = (event.x + 1),(event.y +1)
        w.create_oval(x1,y1,x2,y2,fill="red")

    w.bind("<B1 - Motion>",paint)#画布与鼠标进行绑定
    Label(root,text="按住鼠标左键并移动,开始绘制你的理想蓝图吧。。。").pack(side=BOTTOM)

    mainloop()

    073 GUI的终极选择:Tkinter10

    Munu组件

    Tkinter提供了一个Menu组件,用于实现顶级菜单、下拉菜单和弹出菜单。

    实例1:创建一个顶级菜单(或称窗口主菜单

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()


    menubar = Menu(root)#创建一个顶级菜单
    menubar.add_command(label="Hello",command=callback)#创建一个顶级菜单对象
    menubar.add_command(label="Quit",command=root.quit)

    #显示菜单
    root.config(menu=menubar)

    mainloop()

    实例2:创建添加到主菜单上的下拉菜单

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    #创建一个顶级菜单
    menubar = Menu(root)

    #创建下拉菜单filemenu包含内容
    filemenu=Menu(menubar,tearoff=False)#创建一个从属于menubar的子菜单(下拉菜单)filemenu
    filemenu.add_command(label="打开",command=callback)#创建一个下拉菜单对象
    filemenu.add_command(label="保存",command=callback)
    filemenu.add_separator()#插入分隔线
    filemenu.add_command(label="退出",command=root.quit)
    #创建一个顶级菜单对象“文件”,filemenu从属于这个对象(或称将filemenu添加到顶级菜单“文件”中)
    menubar.add_cascade(label="文件",menu=filemenu)

    #创建另一个下拉菜单editmenu包含内容
    editmenu=Menu(menubar,tearoff=False)#创建一个从属于menubar的子菜单(下拉菜单)editmenu
    editmenu.add_command(label="剪切",command=callback)
    editmenu.add_command(label="拷贝",command=callback)
    editmenu.add_separator()#插入分隔线
    editmenu.add_command(label="粘贴",command=callback)
    #创建一个顶级菜单对象“编辑”,editmenu从属于这个对象(或称将editmenu添加到顶级菜单“编辑”中)
    menubar.add_cascade(label="编辑",menu=editmenu)

    #显示菜单
    root.config(menu=menubar)

    mainloop()

    实例3:创建一个弹出菜单方法

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    def popup(event):
        menu.post(event.x_root,event.y_root)#在此时鼠标位置弹出显示窗口
        
    #创建一个顶级菜单menu
    menu = Menu(root,tearoff=False)

    #创建顶级菜单menu包含内容
    menu.add_command(label="撤销",command=callback)#创建一个顶级菜单对象
    menu.add_command(label="重做",command=callback)
    #创建一个框架
    frame = Frame(root,width=100,height=100)
    frame.pack()

    #将鼠标右键与popup方法绑定
    frame.bind("<Button-3>",popup)

    #显示菜单
    #root.config(menu=menu)

    mainloop()

    实例4:菜单弹出

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    def popup(event):
        menu.post(event.x_root,event.y_root)#在此时鼠标位置弹出显示窗口
        
    #创建一个顶级菜单menu
    menu = Menu(root,tearoff=True)

    #创建顶级菜单menu包含内容
    menu.add_command(label="撤销",command=callback)#创建一个顶级菜单对象
    menu.add_command(label="重做",command=callback)
    #创建一个框架
    frame = Frame(root,width=500,height=500)
    frame.pack()

    #将鼠标右键与popup方法绑定
    frame.bind("<Button-3>",popup)

    #显示菜单
    #root.config(menu=menu)

    mainloop()

    实例5:添加单选组件radiobutton和多选按钮checkbutton

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    #创建一个顶级菜单
    menubar = Menu(root)
    #创建checkbutton关联变量
    openVar = IntVar()
    saveVar = IntVar()
    exitVar = IntVar()
    #创建下拉菜单filemenu包含内容
    filemenu=Menu(menubar,tearoff=True)#创建一个从属于menubar的子菜单(下拉菜单)filemenu
    filemenu.add_checkbutton(label="打开",command=callback,variable=openVar)#创建一个下拉菜单对象
    filemenu.add_checkbutton(label="保存",command=callback,variable=saveVar)
    filemenu.add_separator()#插入分隔线
    filemenu.add_checkbutton(label="退出",command=root.quit,variable=exitVar)
    #创建一个顶级菜单对象“文件”,filemenu从属于这个对象(或称将filemenu添加到顶级菜单“文件”中)
    menubar.add_cascade(label="文件",menu=filemenu)

    #创建radiobutton关联变量
    editVar = IntVar()
    editVar.set(1)

    #创建另一个下拉菜单editmenu包含内容
    editmenu=Menu(menubar,tearoff=True)#创建一个从属于menubar的子菜单(下拉菜单)editmenu
    editmenu.add_radiobutton(label="剪切",command=callback,variable=editVar,value=1)
    editmenu.add_radiobutton(label="拷贝",command=callback,variable=editVar,value=2)
    editmenu.add_separator()#插入分隔线
    editmenu.add_radiobutton(label="粘贴",command=callback,variable=editVar,value=3)
    #创建一个顶级菜单对象“编辑”,editmenu从属于这个对象(或称将editmenu添加到顶级菜单“编辑”中)
    menubar.add_cascade(label="编辑",menu=editmenu)

    #显示菜单
    root.config(menu=menubar)

    mainloop()

    Menubutton组件(希望菜单按钮出现在其它位置时)

    Menubutton组件是一个与Menu组件相关联的按钮,它可以放在窗口中的任意位置,并且在被按下时弹出下拉菜单

    实例1:

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    #创建一个顶级菜单Menubutton按钮,设置为浮起显示(RAISED)
    mb = Menubutton(root,text="点我",relief=RAISED)

    mb.pack(side=RIGHT)#设置为右中显示

    #创建下拉菜单filemenu包含内容
    filemenu = Menu(mb,tearoff=False)#创建一个从属于mb的下拉菜单filemenu
    filemenu.add_checkbutton(label="打开",command=callback,selectcolor="yellow")
    filemenu.add_command(label="保存",command=callback)#创建一个下拉菜单对象"保存“
    filemenu.add_separator()
    filemenu.add_command(label="退出",command=root.quit)
    #显示菜单
    mb.config(menu=filemenu)

    mainloop()

    OptionMenu(选项菜单)组件

    选项菜单的发明弥补了Listbox组件无法实现下拉列表框的遗憾

    实例1:

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    variable = StringVar()#创建字符串变量variable
    variable.set("one")#初始值设置为"one"
    w = OptionMenu(root,variable,"one","two","three")
    w.pack()

    mainloop()

    实例2:多个选项添加到选项菜单中

    from tkinter import *

    def callback():
        print("被调用了")
        
    root = Tk()

    OPTIONS = [
        "Hadley",
        "小土豆",
        "yiwofeiye",
        "RAN"
        ]

    variable = StringVar()#创建字符串变量variable
    variable.set(OPTIONS[0])#初始值设置为"one"
    w = OptionMenu(root,variable,*OPTIONS)
    w.pack()

    def callback():
        print(variable.get())

    Button(root,text="点我",command=callback).pack()

    mainloop()
     

    074  GUI的终极选择:Tkinter11

    事件绑定

    对于每个组件来说,可以通过bind()方法将函数或方法绑定到具体的事件上。当被触发的事件满足该组件绑定的事件时,Tkinter就会带着事件描述去调用handler()方法

    实例1:捕获单击鼠标位置

    from tkinter import*

    root = Tk()

    def callback(event):
        print("点击位置:",event.x,event.y)

    frame = Frame(root,width=200,height=200)
    #Button表示鼠标点击事件
    #1代表左键 2代表中间滚轮点击 3代表右键
    frame.bind("<Button-1>",callback)#按键按下时,调用callback方法
    frame.pack()

    mainloop()

    实例2:捕获键盘事件

    #捕获单击鼠标的位置
    from tkinter import*

    root = Tk()

    def callback(event):
        print("敲击位置:",repr(event.char))#打印当前按下按键的字符
        print(event.char)

    frame = Frame(root,width=200,height=200)
    #Key为键盘事件
    frame.bind("<Key>",callback)#按键按下时,调用callback方法
    frame.focus_set()#获得焦点
    frame.pack()

    mainloop()

    实例3:捕获鼠标在组件上的运动轨迹

    #当鼠标在组件内移动的整个过程均触发该事件

    from tkinter import*

    root = Tk()

    def callback(event):
        print("当前位置:",event.x,event.y)#打印当前按下按键的字符

    frame = Frame(root,width=200,height=200)
    frame.bind("<Motion>",callback)#按键按下时,调用callback方法
    frame.pack()

    mainloop()

    事件序列

    Tkinter使用一种称为事件序列的机制来允许用户定义事件,用户需要使用bind()方法将具体的事件序列与自定义的方法绑定

    Event对象(按键名keysym和按键码keycode)

    实例1:打印当前按下按键的按键名

    from tkinter import*

    root = Tk()

    def callback(event):
        print(event.keysym)#打印当前按下按键的按键名
        print(event.char)

    frame = Frame(root,width=200,height=200)
    #Key为键盘事件
    frame.bind("<Key>",callback)#按键按下时,调用callback方法
    frame.focus_set()#获得焦点
    frame.pack()

    mainloop()

    075 GUI的终极选择:Tkinter12

    Message组件

    Message(消息)组件是Label组件的变体,用于显示多行文本信息。Message组件能够自动换行,并调整文本的尺寸使其适应给定得尺寸。

    实例1:

    from tkinter import *

    root = Tk()
    w1 = Message(root,text="这是一则消息",width=100)
    w1.pack()
    w2 = Message(root,text="这是一条骇人听闻的长消息!",width=100)
    w2.pack()

    mainloop()

    Spinbox组件

    Entry组件的变体,用于从一些固定的值中选取一个。使用Spinbox组件,可以通过返回或者元组指定允许用户输入的内容。

    实例1:

    from tkinter import *

    root = Tk()

    #w = Spinbox(root,from_=0,to=10)#指定输入值为0-10
    w = Spinbox(root,value=("Hadley","小土豆","雅馨"))#指定输入
    w.pack()

    mainloop()

    PanedWindow组件

    与Frame类似,都是为组件提供一个框架,但其还允许让用户调整应用程序的空间划分

    实例1:两窗格

    from tkinter import *

    root = Tk()

    m = PanedWindow(orient = VERTICAL)#设置为上下分布
    m.pack(fill=BOTH,expand=1)#设置为框架覆盖全局

    top = Label(m,text="top pane")#顶窗格
    m.add(top)

    bottom = Label(m,text="bottom pane")#底窗格
    m.add(bottom)

    mainloop()

    实例2:三窗格

    from tkinter import *

    root = Tk()

    m1 = PanedWindow()#默认为左右分布
    m1.pack(fill=BOTH,expand=1)
    left = Label(m1,text="left pane")#左窗格
    m1.add(left)

    m2 = PanedWindow(orient=VERTICAL)
    m1.add(m2)
    top=Label(m2,text="top pane")#顶窗格
    m2.add(top)
    bottom = Label(m2,text="bottom pane")#底窗格
    m2.add(bottom)

    mainloop()

    实例3:显示“分割线”

    from tkinter import *

    root = Tk()

    #showhandle=True表示显示“手柄”
    #sashrelief=SUNKEN表示分隔线的样式设置为向下凹
    m1 = PanedWindow(showhandle=True,sashrelief=SUNKEN)
    m1.pack(fill=BOTH,expand=1)
    left = Label(m1,text="left pane")
    m1.add(left)

    m2 = PanedWindow(orient=VERTICAL,showhandle=True,sashrelief=SUNKEN)
    m1.add(m2)
    top=Label(m2,text="top pane")
    m2.add(top)
    bottom = Label(m2,text="bottom pane")
    m2.add(bottom)

    mainloop()

    Toplevel组件

    Topleve(顶级窗口)l组件类似于Frame组件,但其是一个独立的顶级窗口,通常拥有标题栏、边框等部件。通常用在显示额外的窗口、对话框和其他弹出窗口中。

    实例1:按钮按下创建一个顶级窗口

    from tkinter import *

    def create():
        top = Toplevel()#创建一个独立的顶级窗口
        top.title("FishC Demo")
        msg = Message(top,text="I love FishC.com")
        msg.pack()
        
    root = Tk()
    Button(root,text="创建顶级窗口",command=create).pack()

    mainloop()

    实例2:Toplevel的窗口设置为50%透明

    from tkinter import *

    def create():
        top = Toplevel()
        top.title("FishC Demo")
        top.attributes("-alpha",0.5)#设置为50%透明度
        msg = Message(top,text="I love FishC.com")
        msg.pack()
        
    root = Tk()
    Button(root,text="创建顶级窗口",command=create).pack()

    mainloop()

    076 GUI的终极选择:Tkinter13

    布局管理器

    布局管理器就是管理你的那些组件如何排列的家伙。Tkinter有三个布局管理器,分别是pack、grid和place

    pack:按添加顺序排列组件

    grid:按行/列形式排列组件

    place:允许程序员指定组件的大小和位置

    pack

    实例1:生成一个Listbox组件并将它填充到root窗口

    from tkinter import *

    root = Tk()
    listbox = Listbox(root)
    #fill选项是告诉窗口管理器该组件将怎样填充整个分配给它的空间
    #BOTH表示同时横向和纵向扩展;X表示横向;Y表示纵向
    #expand选项是告诉窗口管理器是否将父组件的额外空间也填满(任意拉伸窗口依旧会填满)

    #默认情况下pack是将添加的组件依次纵向排列
    listbox.pack(fill=BOTH,expand=True)
    for i in range(10):
        listbox.insert(END,str(i))

    mainloop()

    实例2:纵向排列,横向填充

    from tkinter import *

    root = Tk()
    #fill选项是告诉窗口管理器该组件将怎样填充整个分配给它的空间
    #BOTH表示同时横向和纵向扩展;X表示横向;Y表示纵向
    #expand选项是告诉窗口管理器是否将父组件的额外空间也填满

    #默认情况下pack的side属性是将添加的组件依次纵向排列
    Label(root, text="red", bg="red", fg="white").pack(fill=X)
    Label(root, text="green", bg="green", fg="black").pack(fill=X)
    Label(root, text="blue", bg="blue", fg="white").pack(fill=X)

    mainloop()

    实例3:横向排列,纵向填充

    from tkinter import *

    root = Tk()
    #fill选项是告诉窗口管理器该组件将怎样填充整个分配给它的空间
    #BOTH表示同时横向和纵向扩展;X表示横向;Y表示纵向
    #expand选项是告诉窗口管理器是否将父组件的额外空间也填满

    #将pack设置为横向排列
    Label(root, text="red", bg="red", fg="white").pack(side=LEFT)
    Label(root, text="green", bg="green", fg="black").pack(side=LEFT)
    Label(root, text="blue", bg="blue", fg="white").pack(side=LEFT)

    mainloop()

    grid

    使用一个grid就可以简单地实现你用很多个框架和pack搭建起来的效果。使用grid排列组件,只需告诉它你想要将组件放置的位置(行row/列column)。

    实例1:

    from tkinter import *

    root = Tk()

    #column默认值是0
    #默认情况下组件会居中显示在对应的网格里
    #Label(root,text="用户名").grid(row=0)
    #Label(root,text="密码").grid(row=1)
    #设置sticky=W使Label左对齐
    Label(root,text="用户名").grid(row=0,sticky=W)#左对齐
    Label(root,text="密码").grid(row=1,sticky=W)

    Entry(root).grid(row=0,column=1)
    Entry(root,show="*").grid(row=1,column=1)

    mainloop()

    实例2:设置rowspan与columnspan实现跨行和跨列功能

    from tkinter import *

    root = Tk()

    #column默认值是0
    #默认情况下组件会居中显示在对应的网格里
    #Label(root,text="用户名").grid(row=0)
    #Label(root,text="密码").grid(row=1)
    #设置sticky=W使Label左对齐
    #创建Label文本
    Label(root,text="用户名").grid(row=0,sticky=W)
    Label(root,text="密码").grid(row=1,sticky=W)
    #创建输入
    Entry(root).grid(row=0,column=1)
    Entry(root,show="*").grid(row=1,column=1)
    #插入Label图像
    photo = PhotoImage(file="logo.gif")
    #rowspan=2跨两行,边距5
    Label(root,image=photo).grid(row=0,column=2,rowspan=2,padx=5,pady=5)
    #columnspan=3跨三列(默认为居中显示),边距5
    Button(text="提交",width=10).grid(row=2,columnspan=3,pady=5)

    mainloop()

    place

    通常情况下不建议使用place布局管理器

    实例1:将子组件显示在父组件的正中间

    from tkinter import *

    def callback():
        print("正中靶心")
    root = Tk()
    #relx和rely指定的是子组件相对于父组件的位置,范围是(00`1.0),0.5则表示一半,正中间
    #anchor=CENTER表示正中显示
    Button(root,text="点我",command=callback).place(relx=0.5,rely=0.5,anchor=CENTER)

    mainloop()

    实例2:Button组件覆盖Label组件

    from tkinter import *

    def callback():
        print("正中靶心")
    root = Tk()

    photo = PhotoImage(file="logo_big.gif")
    Label(root,image=photo).pack()
    #relx和rely指定的是子组件相对于父组件的位置,范围是(00`1.0),0.5则表示一半,正中间
    Button(root,text="点我",command=callback).place(relx=0.5,rely=0.5,anchor=CENTER)

    mainloop()

    实例3:

    from tkinter import *

    root = Tk()

    #relx和rely指定的是子组件相对于父组件的位置,范围是(00`1.0),0.5则表示一半,正中间
    #relwidth和relheight选项指定相对父组件的尺寸
    Label(root,bg="red").place(relx=0.5,rely=0.5,relheight=0.75,relwidth=0.75,anchor=CENTER)
    Label(root,bg="yellow").place(relx=0.5,rely=0.5,relheight=0.5,relwidth=0.5,anchor=CENTER)
    Label(root,bg="green").place(relx=0.5,rely=0.5,relheight=0.25,relwidth=0.25,anchor=CENTER)

    mainloop()

    077 GUI的终极选择:Tkinter14

    Tkinter提供了三种标准对话框模块,分别是:messagebox、filedialog、colorchooser

    messagebox(消息对话框)

    实例1:askokcancel函数

    from tkinter import *

    print(messagebox.askokcancel("FishC Demo","发射核弹?"))

    mainloop()

    实例2:askquestion函数

    实例3:asiretrycancel函数

    实例4:askyesno函数

    实例5:showerror函数

    from tkinter import *

    #print(messagebox.askokcancel("FishC Demo","发射核弹?"))
    #print(messagebox.askquestion("FishC Demo","买个U盘?"))
    #print(messagebox.askretrycancel("FishC Demo","启动失败,重启?"))
    #print(messagebox.askyesno("FishC Demo","你确定要格式化硬盘吗?"))
    print(messagebox.showerror("FishC Demo","Error!!!"))

    mainloop()

    实例6:showinfo函数

    from tkinter import *

    #options参数可设置为default、icon与parent
    #print(messagebox.askokcancel("FishC Demo","发射核弹?"))
    #print(messagebox.askquestion("FishC Demo","买个U盘?"))
    #print(messagebox.askretrycancel("FishC Demo","启动失败,重启?"))
    #print(messagebox.askyesno("FishC Demo","你确定要格式化硬盘吗?"))
    #print(messagebox.showerror("FishC Demo","Error!!!"))
    messagebox.showinfo("Hadley","Great!!!",icon="info")

    mainloop()

    实例7:showwarning函数

    from tkinter import *

    #options参数可设置为default、icon与parent
    #print(messagebox.askokcancel("FishC Demo","发射核弹?"))
    #print(messagebox.askquestion("FishC Demo","买个U盘?"))
    #print(messagebox.askretrycancel("FishC Demo","启动失败,重启?"))
    #print(messagebox.askyesno("FishC Demo","你确定要格式化硬盘吗?"))
    #print(messagebox.showerror("FishC Demo","Error!!!"))
    #messagebox.showinfo("Hadley","Great!!!",icon="info")
    messagebox.showwarning("Hadley","Warning!!!",icon="warning")

    mainloop()

    filedialog(文本对话框)

    当应用程序需要使用打开文件或保存文件的功能时

    实例1:

    from tkinter import *

    root = Tk()

    def callback():
        #askopenfilename函数用来打开文件
        #asksaveasfilename函数用来保存文件
        fileName = filedialog.askopenfilename()
        print(fileName)

    Button(root,text="打开文件夹",command=callback).pack()

    mainloop()

    实例2:限制打开文件类型

    from tkinter import *

    root = Tk()

    def callback():
        #askopenfilename函数用来打开文件
        #asksaveasfilename函数用来保存文件
        #fileName = filedialog.askopenfilename()
        #限制打开文件类型
        fileName = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GIF",".gif")])
        print(fileName)

    Button(root,text="打开文件夹",command=callback).pack()

    mainloop()

    colorchooser(颜色选择对话框)

    颜色对话框提供一个让用户选择颜色的界面

    实例1:

    from tkinter import *

    root = Tk()

    def callback():
        #colorchooser函数用于打开颜色选择对话框
        fileName = colorchooser.askcolor()
        print(fileName)

    Button(root,text="打开文件夹",command=callback).pack()

    mainloop()

    对应的RGB值及其对应的16进制值

    078 Pygame:初次见面,请大家多多关照

     

    展开全文
  • 敢不敢用一年时间改变自己

    千次阅读 2020-10-22 00:09:21
    文章目录第一部分——心法篇第一章:与其等待生活给你答案,不如自己去发现只要你还能阅读,生活就还有转机不为钱做的事,能让你收货什么稳定的背后,藏着一场地胜算的赌博未知不可怕,可怕的是对未知的恐惧挨过黎明...

    文章目录

    第一部分——心法篇

    第一章:与其等待生活给你答案,不如自己去发现

    只要你还能阅读,生活就还有转机

    不为钱做的事,能让你收货什么

    • 当你内心种下一颗种子的时候,阳光和水就会实适时来到

    稳定的背后,藏着一场地胜算的赌博

    • 当你尝到过梦想的滋味后,现实就如同嚼蜡

    未知不可怕,可怕的是对未知的恐惧

    • 直面恐惧,就象阳光直视阴影
    • 挑战我的并不是荒原和未知,而是我内心的恐惧

    挨过黎明前的黑暗,就是重生

    • 不必知道你的每一步具体该怎么走,只需要坚定方向,然后每次前行200米
    • 人生是可以规划的
    • 职业规划,规划的不是职业,而是自己。它提供了系统的方法帮助我们了解自己,了解自己是谁,喜欢什么,擅长什么,追求什么,如何理解现状,如何应对未来
    • 当你全心全意做一件事的时候,整个宇宙都会协同起来帮助你!!!

    向内走,是光明的道路

    • 在所有关注的问题之中,应该注意将精力集中放在最重要的那一部分,这个道理从小到各个阶段的人生规划,大到一个国家的治理都是适用的。

    • 人生的三大关键词:

      • 自由:
      	我希望我的生活状态是自由的,不受时间、空间和皮囊的约束,可以自主安排时间,有自由施展创意的空间。
      
      • 真理:
      	我想要了解为什么有的人能活出自己,而有的人不能。
          我想了解能够更好识别、激发个体潜能的原理和方法
      
      • 分享:
      	我想把自己的研究、总结出的经验方法分享给大众,让更多人掌握活出潜能的方法,收获丰盛人生。
      
    • 用一年的时间重生,活出无限制的人生

    第二章:与其等世界发现你的价值,不如先为世界创造价值

    只要还有时间,你就永远不会一无所有

    • 上帝宠爱给予者,为你准备的远比你以为的多
    • 没有钱,可以付出时间。
    • 没有时间,可以付出思想,
    • 没有思想,可以付出鼓励的话语。
    • 不用担心你的给予会掏空自己,因为上帝为给予者准备的,远比你以为的多。

    学会这种能力,你就是稀缺人才

    • 勇气的获得只有一种途径:去做你没做过的事情

    吃亏是福,到底“福”在哪里

    • 当你关注价值提供,而非价值收获的时候,你会发现不一样的做事方法
    • 总是主动为他人提供“多一分”价值,这样的思维模式往往能够让我们从常规的做法中独辟蹊径,想出不一样的方法。
    • 当我的注意力放在如何真的支持到他人,如何真的交付价值的时候,就不再介意自己当下的收货和付出是否成正比。
    • 收获并不一定总是以金钱的方式呈现,而这些,是比金钱更宝贵的收获:
      • 有时候收获的形式会是一次优质的推荐
      • 有时会是一位我正好需要的合作伙伴
      • 有时会是一个让我突破自己的机会

    自雇职业,是强者的游戏

    • 让能力撑得起你的梦想
    • 真正的自由人态并不是有钱有闲偶尔出去看看世界这么简单。
      • 真正的自由人态是凭借个人能力,不受时间空间限制为客户创造价值,进而为自己创造经济收入,从而实现移动办公的生活方式
    • 普通人想成为这样的强者,实现自由人态的工作方式,需要完成三个阶段:
      • 深刻的自我认识
      • 知行合一
      • 有市场价值的成长

    自我认识,到底该认识些什么

    • 一切答案都在自己身上

    • 1、认识人生目标

      • 人生的困境常常来自执着于“如何达成”的路径,而忽视了“为什么要达成”的意义,这种思维倒置称为“方向-路径混淆思维”
      • 千万要避免 战术上的勤奋掩盖战略上的懒惰
    • 2、认识自我优势

      • 优势只在初入某个领域内,能起到快速领悟的作用
      • 而要达到高手级别还需要类似一万小时、刻意练习式的投入
      • 如果寄希望于找到优势,人生就能马上开挂逆袭,注定是要失望的
      • 我们在某些方面的优势只是能让我们有新手的运气,最终突围需要的却是远征者的勇气和耐力!!!
    • 3、认识隐秘卡点

      • 我们既然有容易上手的优势地方,就一定会有容易被卡住的地方。
      • 如果缺乏对卡点的认知,就容易反复在同一个问题上不断经历挫败,却看不到事件背后的卡点,以为生活故意跟自己过不去
      • 每个人都有过被卡住的感受,但是真正卡住我们的往往并不是事件本身,也不是事件中的人。卡点的源头最终都是我们自己,我们自己对这个事件的看法。
      • 经常提醒自己:让我不舒服的不是这个人,不是这件事,而是内在有未被化解的卡点。那些让我伤心痛苦的人,其实都是来度我冲破这个卡点的!!!
    • 认识人生目标、自己的优势天赋和人生的隐秘的卡点,组成了自我认识的三大板块,脱离了这三个板块的自我认识都是隔靴搔痒

    • 你解答这三个问题所需要的时间,就是你实现自己理想生活所需要的时间

    • 静下心来向内走,这才是光明的道路!!!!!!

    所有道理你都必须去体验,才能真正知道

    • 人格测评工具:星盘、玛雅历、盖洛普、MBTI、霍兰德、九型人格、生命数字、紫微命格等
    • 如果一份工作,缺乏心智上的挑战,并且侵占我太多思考研究的时间,我就会排斥。反之,如果一件事情,需要大量的思考,并且工作内容是研究心智的成长,即使没有薪酬,我也会甘之如饴。
    • 对自己的认识,从一种无意识的理解进入了有意识的理解,在自己做出的每一个行为背后,都会知道是什么在发挥作用。
    • 在寻找自我探索方法之前,先要知道自我探索的意义,是因为“为什么”永远比“是什么”、“怎么做”更重要!!!!!!

    不以市场价值为目标的成长,都是自嗨

    • 市场是检验成长的试金石
    • 只要你还有物质生活的需要,还在追求更高品质的生活和生命体验,那么成长就需要以实现市场价值为目标,这其中包含两层含义:
      • 你的成长是否有效,你说了不算,市场说了才算
        • 真相是,如果得不到市场的认可,没有客户愿意用钞票给你投票,再好的成长、创意也没用
      • 你需要市场的认可,才能继续成长:
        • 任何个人或公司想要持续发展,都离不开对自己的再投资,例如:购买更先进的设备、引进更优秀的人才、投入更多的科研经费、参加更高阶的学习等等
        • 在产品上,提供超出客户期待的价值
        • 在体验上,让客户感觉方便舒服
        • 在服务上,让客户超值、超预期的享受
        • 在获得市场认可后,不满足于此,继续再投入升级产品和服务,才能立足于市场,也才有持续成长的机会

    跨越式成长是有规律可循的

    • 成长三阶段:深刻的自我认识、知行合一、有市场价值的成长
    • 结构化思考,系统化做事
    • 结构化个人成长,还需要群体实践:一套方法是否有效,必须脱离特殊性,走向普遍性,必须经得住群体的考验!!!!!!

    第二部分——方法篇

    第三章:明确三年愿景,配置人生导航系统

    学会在枯燥的工作中创造乐趣

    • 高学历和如意人生之间并没有直接的因果关系
    • 职场人大部分离职的动机,都值得深入分析,进一步剖析。如果是为了逃避现状,而寄希望于换工作来解决兴趣不明、能力不及、专业缺乏的问题,那只会越换越糟糕!!!

    明确内心热情之后,一样的工作就有了不一样的意义

    围绕关键词,设计自己想要的生活

    人生关键词,一座永不熄灭的灯塔

    要执着于明确方向,而不是执着于明确路径

    • 如果把职业困惑比喻成一团“乱麻”,与其耗时耗力去整理麻线本身,不如先停下来仔细观察,找到线头的位置,这样才能事半功倍。
    • 很多职业上的困惑,往往不是因为不知道怎么做,而是没有提出正确的问题。
    • “条条大路通罗马”,仔细看这句话你会发现,“罗马”是明确的目的地,而如何去罗马的路径是不明确的,而且还有很多种可能。任何一条道路都可以通罗马,但是最重要的是“罗马”,而不是去罗马的“路”。
    • 活得明白,知道目的地,但不纠结路径
    • 活得糊涂,纠结于路径,却不知去哪里
    • 没有灵光乍现的时刻,也没有菩提树下顿悟的神迹。对自我的探索其实是枯燥又单调,无非就是反思、分析、理解、观察和体悟!!!

    在人生的海洋上,你需要一座永不熄灭的灯塔

    • 人生关键词是你此生的目的地,是你能想象的最高版本的自己。
    • 它像灯塔一样,指引你航行在人生的海洋上,你不需要直到每一海里具体该怎么走,你只需要一直朝着灯塔的方向,不断修正方向,不断靠近!!!!!!
    • 人生关键词的价值:
      • 能够让你在面对人生十字路口的时候,做出适合自己的选择
      • 能够让你在面对生活诱惑的时候,不忘初心
      • 能够让你在遭遇瓶颈的时候,创造性地冲出重围

    自由书写,听见你内心的声音

    如何听见内心的声音

    • 乔布斯在2005年斯坦福大学毕业典礼上的演讲:

      • 不要让其他人喧嚣的观点掩盖你内心真正的声音。更重要的是,你要有勇气去听从你直觉和心灵的指示————它们某种程度上已经直到你想要成为什么样子,所有其他的事情都是次要的。
    • 做自己,因为别人都有人做了。————英国作奥斯卡·王尔德

    • 不能听命于自己者,就要受命于他人。————德国哲学家威廉·尼采

    • 世界上最伟大的事,是一个人懂得如何做自己的主人。————法国思想家蒙田

    • 听见自己内心声音的方法————自由书写

      • 一个问题回答100遍!!!!!!
      • 这个问题就是:如果你有足够的时间和金钱,这辈子你会做哪些事情?

    一次完整的自由书写过程(案例)

    • 1、关掉手机、壁上房门,独自坐在书桌前,翻开笔记本崭新的一页,在第一行写下:如果我有足够的时间和金钱,这辈子我会做哪些事情
    • 2、然后开始放松自己,让自己的思绪进入假象世界,在这个世界里我有用之不尽的财富,不需要工作来养活自己。事实上,我唯一的工作就是做自己喜欢的事。
    • 3、不停的记录脑袋里冒出来的想法,不去考虑是否实际,不去考虑是否低俗,只需要忠诚地记录下头脑中的想法。
    • 4、如果中间被卡住,闭上眼睛深呼吸,然后在心里继续问自己同样的问题。放空自己,试着不去操控思维,就静静的等着,等着脑袋里蹦出新的念头。
    • 5、作者案例,我写到90多条的时候,发现落笔写字的速度比头脑里的念头要快,非常非常细微的差别,简直可以用毫秒计算,但是我清楚不是我脑袋里先有念头,然后转化为文字,而是在念头产生之前,文字就已经有了。

    简单的方法,不简单的意义

    • 内心的声音,不是语言组成的,而是一种更纯粹的存在,它的存在快到思维来不及加工。当你意识到“我怎么会有这种想法”的时候,你就已经不在这股纯粹中了。
    • 为什么长时间不间断的书写会产生这种纯粹时刻呢?
      • 首先,自由书写的问题设定了一个前提:有足够的时间和金钱。在这种前提下,我们需要打破日常的思维习惯,尝试用一种全新的视角去思考
        • 现实生活中我们有很多想做的事情,但是因为各种各样的原因无法实现,例如:想出国留学,因为没有钱放弃了;想做一份自己的视野,孩子还小需要照顾放弃了;想环球旅行,没有时间放弃了。。。。。。
        • 正是因为生活中很多现实的限制,让我们没有办法进一步思考下去。
        • 自由书写就很好的突破了这个限制,给了我们一次机会跳出日常生活的琐碎,突破限制,尽情想象!!!
      • 其次,自由书写的问题可以帮助我们把自己调整到理想的生活状态,去跟“高我”进行链接,让更高版本的自己指导现在的自己。
      • 最后,自由书写是很好的自我对话方法。它很简单,几张白纸、一支笔就可以完成。
    • 越是浮躁的时候、越是快速变化的时代,我们越需要回到自己的内心,去听内心的声音。当我们反复问自己一个问题100遍的时候,相当于穿透了我们的表意识,去跟潜意识进行沟通,让深埋在内心深处的想法浮出水面!!!!!!
    • 人之所以痛苦,是因为内心的呐喊没有被听到。一旦你听到内心的声音,跟自己的内心链接在一起,外界的困扰实际上是很容易突破的。
    • 在朝着生活目标前行的过程中,我们需要明确的是目标,而不要执着于路径。
    • 只要不断确认自己现在做的事情是在接近目标状态就好,从路径执着中抽离出来,我们就不会痛苦!!!

    偶像人物分析,显化你内心的愿景

    大师的偶像榜样

    • 如果说自由书写是向内看,去倾听内心的声音,那么偶像人物分析就是向外看,去显化你内心的声音。
    • 人人都应该有自己的精神偶像,并不是个人崇拜,而是因为偶像就是你在现实世界中看到的最高版本的自己。因为他们的存在,你才知道你的目标状态是可以达成的!!!!!!

    请你的偶像为你显化愿景

    • 偶像可以是历史人物,也可以是社会名人,还可以是你身边的家人、朋友、同事等。
    • 我们可能会欣赏很多人,而我们的精神偶像应该是我们想要成为的人。问自己这样一个问题:谁的人生经历是你也想体验的?请列举三位并说明理由。
    • 如果找不到精神偶像怎么办?那么可以多阅读,特别是人物传记和人物故事。可以多去参加一些论坛讲座或者社群活动,去看看其他人的生活。跟随你的内心,自然地靠近一些你喜欢的人,去多了解他们的故事。在这个过程中,你不仅能找到你的精神偶像,还能明确你想要的生活状态。
      • 有时候,不是你不知道,而是你知道的太少。

    答案一直在你身上

    • 通过自由书写向内探索,偶像人物分析向外显化,最终提炼出三个人生关键词。他们将作为我们航行的灯塔,远征的指南针,帮助我们修正方向,指引我们通向属于自己的人生宝藏。

    第四章:挖掘你的优势,设计个人事业最优路径

    真实案例:珍惜天赋最好的方式是投入

    是天赋 + 投入 = 优势

    • 天赋的感觉,做某件事得心应手就好像训练过一样!!!
    • 天赋是上帝送给每一个人的礼物
    • 天赋能让你在做某件事的时候上手很快,但是真正让你脱颖而出的优势则需要持久地练习,以达到优于别人的水平。

    做自己不敢做的事,才会有成长

    • 把喜欢的事情当饭吃的过程中,很多人会有这样一个误区:一定要完全准备好,才敢去市场上兑换价值。但是,事实是你不去实践,你永远也不会准备好!!!
    • 一边忐忑一边前行,你才能在不断尝试中,拓展自己的边界,遇见生命中贵人。
    • 一定不能给自己设限

    求助是一种能力,勾搭是一门神技

    • 成长,从来都不是一件可以闭门造车的事情
    • 一定要让自己在各行各业中都有师傅,勾搭师傅的途径可以是各式各样的。刷微博给喜欢的博主发表白私信,泡QQ认识一群天南地北的朋友,甚至在网易云听音乐也能链接到里面的小伙伴。不一定要是专家大咖才是师傅,每个人身上都有你值得学习请教的地方。
    • 不用担心自己的问题很初级被人笑话,向人请教问题时会认真梳理自己的语言,表达清楚自己的意思,列举已经尝试过的方法。
    • 在互联网时代,资讯已经不再稀缺,稀缺的是有针对性、能个性化指导的咨询。想要在新领域快速学习,就需要具备快速拣选高浓度、高参考度的信息。跟同行前辈请教,无疑是最直接和最有效的方式,告诉别人你的困惑,礼貌友好地请他人给予支持和帮助,并不是你不如人的佐证,反而是内心强大的表现!!!!!!

    人生寻宝图,读懂你的无字之书

    最该读的是你自己这本“书”

    • 你有没有想过,为什么总是对某些事情热忱不减;有没有观察过自己的行为有某种规律模式;有没有总结过在哪些特定的情形下你容易超常发挥?
    • 每个人都是一部无字之书,它记录了你的喜怒哀乐、天赋,只要稍微有用心你就能发现蛛丝马迹。而你心心念念的热情,就存在于这些蛛丝马迹之中,等待你抽丝剥茧去发现。
    • 如果说人生关键词是前行的灯塔,指引你始终航行在使命的方向上。那么你还需要一张人生寻宝图,它像一张地图,可以告诉你最适合你的寻宝路径。
      • <注意>:人生寻宝图只有在你知道目的地的时候才有用,如果你还不清楚你的目的地,也就是你的人生关键词,那么执着于路径是没有意义的!!!!!!
    • 这张地图是由你的经历绘制而成的,当你仔细回溯过往经历时,你会发现你总是被某一类事情和体验所吸引,在那个事件中你感受到全然的兴奋和骄傲,就像站在人生的高峰一般,即:高峰事件

    回忆高峰事件

    • 人生寻宝图的可贵之处在于它的结果完全来自你的经历感受。
    • 如果留心观察,你还能发现人生寻宝图里的热情线索,和你的偶像经历也会有很多的相似之处。这就是说你之所以会崇拜一些人,是因为你原本就有成为他们的基因。

    绘制人生寻宝图,发现你的热情线索

    绘制人生寻宝图

    • 第一步,准备一张白纸或空白笔记本。在白纸中间画一条横线,将纸面分为上下两个部分。
    • 第二步,开始回忆你能想到的最早的一件高峰事件。(高峰事件不需要轰轰烈烈,只要你觉得当时这件事情完成之后你特别骄傲自豪即可)
    • 第三步,回忆起这样的事件后,感受它带给你的兴奋感,然后在横线上面找一个合适的位置画圈代表这件事。(画的越高,代表这件事越让你兴奋)
    • 第四步,在圆圈处给这件事取一个精简的名字,比如:考上理想大学、带全家旅行、自己买了房子等等。
    • 第五步,以第一件高峰事件为起点,以横线为时间线,将你能回忆起来的所有高峰事件都标记出来。
    • 第六步,人生除了一些高峰事件外,还有很多低估的时期,请用相同的方法,把那些让你觉得挫败、遗憾,甚至后悔的事情标注在横线下方。
    • 第七步,将这些高高低低的圆圈,按照时间顺序连成线
    • 结果:这张心电图似的折线图,就是你的人生寻宝图,里面藏着你的道路和卡点。

    读懂人生寻宝图

    • 完成人生寻宝图的绘制之后,把每一件高峰事件都放在下面的问话中问问自己,并记录下你的回答:
      • A. 当时你为什么想做这件事?
      • B. 它(上一个问题的回答)为什么会吸引你?
      • C. 这个过程中,让你享受的环节是什么?
      • D. 请用一个词语概括这件事吸引你的核心
    • 当你按照这组问话逐一完成所有高峰事件的分析后,你会发现,让你兴奋的事件虽然不一样,但是背后吸引你的、让你享受的本质是一样的。这就是你的热情所在,答案一直在你身上,向内走才是光明的道路!!!!!!

    长板让你优秀,短板让你有朋友

    样样懂,不如精一样

    • 木桶短板理论:一个木桶能装多高的水位,由组成这个木桶的最短的那个板子的长度决定。
    • 短板理论在升学考试场景下是适用的,但是当我们离开校园进入职场之后,游戏规则就不一样了,不管什么工作,都离不开协作:跟领导协作、跟同事协作、跟客户协作,我们相互协作的时候,都希望对方在这个领域是专业的、优秀的。
    • 协作产生的基础,就是你擅长的部分,对方不擅长;对方擅长的部分,你不擅长。
    • 因此,在职场中,短板理论就不再适用了。相反,你需要尽可能的精进长板优势,让它成为你的名片、代名词,成为你不可替代的理由。
    • 上帝给我们优势,是希望我们发光,给我们劣势,是希望我们有朋友。
    • 所以对于短板,只要没有严重影响你基本能力的发挥,就找擅长的人去协作吧!!!
    • 如何知道自己的优势是什么呢?人生寻宝图,不仅能帮你找到天赋热情的线索,还能帮你识别出你的优势!!!!!!

    识别你的优势

    • 很多人不知道自己的优势是什么,是因为优势是每个人最自然、最擅长的思考和行为方式。优势对你来说就像走路一样自然,以至于你都没有察觉到:天哪,我居然会走路!
    • 所以当你拿着放大镜去仔细回顾高峰事件的时候,你就能从中发现优势的蛛丝马迹,即:将你的高峰事件按照下面的问话方式问问自己,并记录下你的回答:
      • A. 完成这件事的过程中,你遇到了哪些挑战?
      • B. 面对这些挑战,你是怎么做的?请描述具体过程?
      • C. 请从你的做法中,提炼出你的优势能力。
    • 当你按照这组问话逐一完成所有高峰事件的分析后,你就能总结出自己的能力:那些反复运用到的能力就是你的优势所在!!!
    常见能力词汇

    变化的是职业,不变的是优势能力

    • 一份职业干到老的时代已经过去,未来是不确定的时代,对人才适应变化的要求也会越来越高。
    • 生涯之学乃应变之学。————生涯咨询领域的泰斗人物金树仁老先生
      • 意思就是,职业规划是一门关于应变的学问,它通过让你了解自己和外部世界,提前为不同阶段做好准备,并掌握应对变化的自我调适方法。
    • 外部职业世界的变化是迅速的,而内在的自己是稳定的,以不变应万变才是职业规划的价值所在。
    • 当你从人生寻宝图和高峰事件中发现了自己的热情线索和优势能力之后,就相当于找到了内在稳定的部分,剩下的工作就是不断重组这些文档的部分来适应外部变化。这个过程,就是制造可能性的过程。

    开启你的钻石人生

    结构的威力

    • 什么是人的结构?就是要素的组合方式。
    • 钻石人生:由四个部分组成,就像钻石的四个碳原子一样,分别是:热情、知识、优势和资源

    钻石人生的结构

    • 热情:指内心对某件事强烈的兴趣,忍不住想要深入了解的动力。
    • 知识:指在某些领域掌握程度超过平均水平。
      • 高于平均水平的一个标准,就是这个方面的知识你能系统地传授给他人,市场愿意为了获得你这方面的知识而给你付费。
      • 实际上,任何一个领域,只需要持续投入20个小时的有效练习就能入门。
      • 入门之后,继续投入50个小时的有效练习就能达到合格的水平,也就是说,任何事情你只要投入100个小时的有效练习就能超过平均水平。
    • 优势:指做某件事轻而易举的能力,看起来就像接受过训练一样
      • 对优势最好的珍惜就是持续不断的投入,使之成为你不可替代的竞争力。
    • 资源:包括房产、汽车、设备等有形资产,也包括经验、学历、人脉、城市等无形资产。
    • 资源整合不等于不劳而获,对资源的合理优化配置可以营造良好的外部环境,更有利于个人价值的体现!!!!!!
    • 以上就是钻石人生图的四个方面,所谓逆袭就是不断提升、重组这四个方面的过程!!!!!!
    • 当你带着结构的思维去规划你的人生时,才能收获结构的红利,如同钻石一样,从结构中获得稳定性和稀有性。

    发现问题,问题就解决了一半

    绘制你的钻石人生图

    • 以满分为 10 分为标准,分别给自己的热情、知识、优势、资源四个维度评分,写出四个方面具体的内容。
    • 绘制钻石人生图的价值,不是看自己有多少分,而是看清自己的现状以及问题的成因。

    常见的钻石人生图特点

    • 对于多数人而言,钻石人生图大致会出现三类情况:
      • 第一类是,知识和优势分数比较高,但是热情分数很低,感觉工作生活没有激情,想要改变现状却不知道从何下手。
      • 第二类则相反,热情分数比较高,但是知识、优势分数比较低,也就是能力还撑不起自己想要的生活,感觉无力甚至怀疑自己是不是走错了方向。
      • 第三类则是,热情、知识、优势分数都挺高,但资源分数偏低,那么就会有怀才不遇的感觉,或势能迟迟起不来。
    • 不管是有热情没能力,还是有能力没热情,当你亲手绘制处自己的钻石人生图之后,都会有一种恍然大悟的感觉,原来问题杵在这里。
    • 钻石人生图并不高深,只是利用一个简单的工具,把你当下的状态形象化呈现出来,你就能理解问题的症结所在

    找准切入点,自然事半功倍

    • 例如,在热情、知识、优势、资源都偏低的情况下,可以先从热情入手:
      • 先清楚自己想要成为什么样的人,想过什么样的生活,明确自己的使命,然后再去学习跟使命方向一致的知识。
      • 在这个探索过程中,你的优势自然会得到提升,而资源也会相应地打开局面。
    • 所谓有结构地成长,就是根据当下的状态,找准切入点启动成长。实现阶段突破进入下一阶段后,继续找准切入点带动成长。如此循环往复,最终实现升级和突围。

    第五章:制订专属年计划,开启个人事业

    真实案例:家庭、副业、职场都是练习场

    无法兼顾,那就试试整合吧

    • 第一个——法宝:把家庭、副业和职场都当成练习场,整合起来运转,而不是分割成彼此割裂的部分。
    • 要达到这个状态,核心关键是情绪修炼:
      • 情绪沟通:例如,安抚孩子上幼儿园
      • 情绪调节:例如,再工作中接到临时额外任务的时候
      • 情绪释放:例如,在被爱人“放鸽子”取消烛光晚餐的手
      • 情绪引导:例如,在帮助团队小伙伴解决棘手问题的时候
    • “分”的思维能让我们术业有专攻,社会分工更明确,运转更高效。而在生活中,我们则需要更多使用“合”的思维,找到自己“合”的主线。

    人生关键词让人生忙而不乱

    • 第二个法宝——定位自己的人生关键词,例如:内外兼修、分享价值、平衡三个关键词,尽管看起来做了很多事情,很忙碌,但实际上就是在围绕这三个关键词开展,所以可以做到忙而不乱。

    停止内耗,能掌控的永远只有当下

    • 第三个法宝——不忧过去,不惧未来,停止内耗。
    • 停止内耗,这是多么帮的生活态度啊!!!
    • 其实很多人,在做事情A的时候担心事情B,在做B事情的时候担心事情A,这种看不见的情绪内耗才是吃点效率的罪魁祸首。

    “幸福苹果树”,重新定义你的生活方式

    整合就是最好的平衡

    • 实际上,工作、家庭、事业、个人成长都不是彼此独立、相互分割的,它们本来就是一个整体,这个整体叫“生活”。
    • 生活的真相是,变化永远比计划快,试图在各种不确定性中坚持所谓的“1:1家庭事业平衡”几乎是不可能的,反倒给自己招来无法掌控生活的挫败感和打击!!!
    • 你需要的仅仅是在生活中给自己理清一条主线,串联起你的家庭、事业和个人世界,那么过日子本身就是坚持。
    • 个人成长不再局限于一小时的阅读时光,反而扩展到无限的生活空间。过日子本身就在学习成长,还有比这更好的工作生活平衡方式吗?

    “幸福苹果树”,重新定义你的生活方式

    • 通过自由书写和偶像人物分析,再结合人生寻宝图和钻石人生图,你已经非常明确了属于自己的三个人生关键词,清楚自己想要成为什么样的人、过什么样的人生,并且知道了你自己的热情线索。那么,接下来你应该如何将这些抽象的认知融入鲜活的生活呢?
    • 因此,需要一条主线来整合你的工作和生活,例如:你的关键词之一是真理,那么:
      • 探索个人潜能的发展规律,总结出行之有效的方法
      • 因此,一切跟个人潜能有关的学科、领域、经验、知识都应是你的练习场。
    • 如果把终身成长理解成一颗蓬勃生长的苹果树,那么个人潜能就是我的“苹果树干”,是我一切发展的重心和支撑。
    • 然后我以探索个人潜能发展规律的视角重新审视了工作生活的其他方面,有连接的部分就优化加强其中的意图和方法,没有连接的部分就减少这件事在我生活中的比重,甚至是舍弃。
    • 我不再觉得自己需要切换身份去应对生活的不同场合,而是从内在升起一股合一感,因为我了解到:我做的所有事情都来源于并指向一个方向。

    种下你的“幸福苹果树”,最容易的坚持是生活

    画出“树干”

    • 按照自由书写、偶像人物分析、人生寻宝图和钻石人生图的梳理,提炼出三个人生关键词。
      • 通常这三个关键词中:
        • 有一个词代表的是你和自己的关系,比如:滋养、自由、平衡等,强调的是你理想的身体和精神状态。
        • 有一个词代表的是你和外界的关系,比如:分享、影响、助人等,强调的是你理想中跟外界的互动关系。
        • 还有一个词代表的是你的价值所在(或者说你在这个世界上的“代言身份”),比如:我的关键词真理,就是希望自己能透过现象看到本质,把本质的价值带给世界,活出“真理代言人的身份”。
      • 找到这个代表你价值和化身的关键词,在一张白纸的中心位置画出树干,并写上这个关键词。
      • 这将是你未来 3-5 年的主线,通过它筛选、整合你工作生活的所有面向,你就能抵御干扰你的诱惑,同时形成自己的主心骨,在信息爆炸的洪流中也不会迷失,反而能怡然自得地坐在一叶扁舟上静观潮起潮落,我看云卷云舒。

    找出“苹果”

    • 接下来,在白纸的边角处罗列出目前你所有的工作生活项目,尽量细化和全面。
      • 例如:不要单纯地写“工作”,而是要具体写出工作中你主要负责的板块,像客户沟通、报表分析、设备检查等等。可以尝试把工作分解为对上跟主管的模块、对下跟下属的模块、对左跟客户的模块、对右跟同事的模块,中间是自己工作能力提升的模块,写出对应的常态工作内容。
      • 同时,生活也可分解为多上跟父母的模块、对下跟孩子的模块、对左跟伴侣的模块、对右跟朋友的模块,中间是自己个人成长的模块,写出对应的常态生活内容。
    • 罗列出以上所有内容之后,逐一将其跟你的树干关键词连接,看是否能重新定义你在做的事情或将要做的事情。
    • 那些跟树干关键词关联度低的事情,应该果断舍弃或者授权给他人协助完成。
    • 当你列出所有苹果和树干的连接方式后,你就会知道哪些领域是你学习的重点。这样一来,你就能在海量的学习内容中,找到自己需要的,而不至于陷入学习的焦虑中!!!!!!

    最容易的坚持就是生活

    • 完成这个过程后,你就种下了一颗属于自己的“苹果树”:
      • 树干是你的修炼核心
      • 树上的苹果是你的工作生活内容
      • 每一个苹果都经过了筛选和重新定义而跟树干相连接。
    • 通过照料“苹果”,你的“树干”得到丰富的滋养,越来越茁壮
    • 反过来,茁壮的“树干”,又能支持苹果树长出更多更大的“苹果”。
    • 整个过程就是你的生活,你无须在照顾家庭的时候担心自己没有投入工作而落后于他人,也无须在工作的时候因为没有陪伴家人而感到歉疚。
    • 过去这些浪费在焦虑、犹豫、迷茫的时间和精力,通通可以节约下来,用来去做更有价值的事情。
    • 你的思考的方式和做事的心境会完全不一样,日积月累带来的差异就是平庸跟卓越之间的距离!!!!!

    重生年计划,用一年的时间重生

    清晰就是力量

    • 如果一件事情既不是你内心深处真实的渴望,又不是你擅长的事情,只是看见别人做发生了改变,就强迫自己去做,那么光是花在强迫自己去做的精力就耗费了大半意志力,还有多少意志力能够支撑自己坚持下去呢?
    • 所以,在确定一个方向准备持续坚持之前,想清楚自己要什么,进行深刻的自我认识是非常有必要的,这个过程哪怕慢一点也没关系,厚积才能薄发!!!!!!

    有系统地成长

    • system: Save Your Time, Energy and Money.(节约你的时间、精力和金钱)
    • 系统:做一件事情倘若能从系统的角度触发,让事情本身成为系统中的一环带动其他环节的发展,那么就能达到四两拨千斤的效果。
    • 做一件事情的同时达到多重效果,就是系统化思维带来的倍速成长。

    指定有系统效能的重生年计划

    • 重生年计划之所以不同于普通年计划,就是因为它具备清晰和系统效能的价值。
    • 重生年计划由五个部分组成:
      • 人生关键词
      • 关键词描述
      • 优势路径
      • 量化目标
      • 四维度日程
    • 其中,人生关键词和优势路径的价值就在于清晰————清晰地知道自己要去哪里以及如何去,这就是方向感
    • 同时,人生关键词和优势路径之间,又是路径和四维度之间又形成循环系统,相互促进、倍增效果。

    重生年计划

    人生关键词
    • 什么是重生:你有一个主心骨,你只是每年在这个主心骨上不断升级,从点做到面,从面做到体,从体做到生态。
    • 第一步:提炼人生关键词(参考第三章:自由书写):
      • 绝大部分人的理想生活状态都可以归纳为:学习、旅行和帮助他人
      • 之所以要进一步深挖和提炼,是因为每个人有不一样的个性特质。
      • 真正能指引你的人生关键词,一定是带有你个人特色的,即便是相同的词,每个人的理解也是不一样的。
    • 第二步:关键词描述
      • 每个人对词汇的理解不一样,即便是同一个关键词,不同人的解读也会有不同的含义
      • 关键词描述的意义在于让你透过单词本身去链接关键词带给你的感觉。
    • 第三步:优势路径(参考第四章:人生寻宝图)
      • 如果说人生关键词是你理想人生的目的地,那么优势路径就是你去往目的地的道路,而且是最适合你的快速通道。
      • 从你觉得很有成就感的事情中发现热情线索,再结合关键词和优势能力就可以指定适合你的优势路径。
    重生年计划表格
    - 首先,人生关键词激活了内在动力,再结合优势能力和热情线索做自己喜欢擅长的事,行动计划就变得更容易坚持,也更容易取得成效。
    - 其次,经过人生关键词筛选出来的学习领域,能够让你在信息洪流中避免干扰,始终有清晰的主线,不至于样样都想学却什么也没学好。
    - 最后,人生关键词明确了未来三年到五年的愿景,又是路径明确了具体路径,每年只需要在此基础上精进就好,相当于一年学习行动方案。
    - 如此一来,你会发现你的人生变得特别简单和清爽,少了很多纠结和混乱,更能享受生活的乐趣。
    
    • 第四步:量化目标
      • 有了目标和方向,接下来要做的就是设定可量化的目标。
      • 可量化:指的是能准确用数字或者具体状态来评估完成效果的标准,例如:
        • 大学生设定“找一份工作”,量化成“找一份在一线城市月薪6000元的有发展前景的工作”
      • 计划除了需要有量化目标外,还需要量化的目标是合理的。
    量化重生年计划示例
    • 检验量化目标是否合理的一个简单方法是,把年目标分解成月目标,看是否有足够的时间精力去完成。
      • 把量化目标调整到自己能接受的范围,从而保持自己处于匀速前进的状态,而不是短跑冲刺的状态。
      • 一口气给自己制定太多计划,过分透支精力不仅不利于身体健康,还极有可能完成不了目标,引发挫败感。
    减量重生年计划示例
    • 经过多年经验总结,我发现:效能感来自工作生活中的成果,幸福感来自良好的人际关系。当你在生活中能持续感受到成就感和幸福感的时候,你就有持久的耐力去践行年计划的目标

    提升效能感和幸福感————四维度日程管理法

    1.效能感的来源————输出

    • 四维度日程管理法,由输出、输入、开源、固本四个维度组成。
    • 输出:指的是为他人产出价值,其方式有很多,比如:
      • 读书笔记、观影笔记、课程分享,跟家人朋友分享心得,高质量完成工作任务等
      • 输出不仅需要有价值,更重要的是需要对他人有价值!!!!!!
    • 如果你感觉你自己很努力却依然很穷,通常就是为他人输出的价值不够多或不够好!!!!!!
      • 检查一下你每天的时间,有多少是花在为他人产出价值的事情上,你就知道改变该从哪里开始了。

    2.持续输出的源泉————输入

    • 输入:指的是为输出提供养料
    • 只要有心,无时无刻都可以进行输入学习
    • 静下心来思考一下你的工作生活,想一想什么技能和知识在三年之后能帮到你,就从现在开始去接触、去学习。
    • 生活就是教室,职场就是考场

    3.让你事半功倍的方法————开源

    • 开源:指的是创造链接、拓宽视野的事情
    • 成长不是一条单行道,在自己的业务领域待久了,思维往往会固化,反而会制约发展
    • 跨学科学习:如果你手里只有锤子,那么看什么都是钉子。跨学科、跨界学习能让你的“工具箱”里不仅有锤子,还有扳手、螺丝刀和锯子。
    • 你能提供的解决方案越多,你的个人价值也就越大。
    • 除了跨界学习,开源还有拓展人际链接的意思。即使个人能力再强,也不可能脱离社会分工和协作。多元丰富的人际关系能够成倍放大你的个人价值,增加未来的可能性。

    4.自制幸福感的配方————固本

    • 真正让我们感觉幸福的事情,往往来自细微之处:
      • 跟自己独处1个小时
      • 做10分钟的静心冥想
      • 给自己做一顿丰盛的早餐
      • 对伴侣表达感谢
      • 和孩子一起玩游戏
    • 这些关照健康、滋养内心、经营重要关系的事情,称之为“固本”。
    • 快速成长:你有一个主心骨,你只是每年在这个主心骨上不断升级,从点到面、从面到体、从体到生态
    • 手忙心闲,忙碌在热爱的事情中,平和喜悦自在心间。
    • 通过明确人生关键词,践行四维度日程管理法!!!!!!

    5.四维度日程管理法规划你的每一天

    • 生活就像跷跷板,一边是个人实现的成就感,一边是融入关系的幸福感。过分侧重任何一边,都会造成失衡。
    • 每天晚上,抽10分钟的时间根据输出、输入、开源、固本规划第二天的日程,具体步骤如下:
    重生四维度的一天
    • 第一步:在当天晚上把第二天要做的事情根据四维度分类规划好,尽量让四个维度都有事情做。
    • 第二步:快速评估一下四个维度的待办事项是否过量,尝试把大事项分解成小事项,分多日多次完成。
    • 第三步:不要把日程安排得太慢,留出一点空余时间,以便灵活应对临时任务。
    • 第四步:特别重视固本维度,不要因为待办事情多,就压缩滋养自己的时间。
    • 第五步:第二天结束时,做一个快速复盘。看看哪些内容如期完成,新增了哪些内容,又有哪些内容没有完成,根据情况进行调整再做下一天的安排。
    • 试想一下,如果每天你都能做一点为他人床在价值的事情(输出),做一点为成长积累学习的事情(输入),做一点跨界链接、拓宽视野的事情(开源),做一点关照自己、回馈家人的事情(固本),而这些事情都跟你的人生关键词紧密联系,那么你的精力、时间就会像从放大镜中穿过的阳光,经过折射聚焦在一个单点,产生足以点燃火堆的能量。同样,这也是能让你用一年时间实现重生的能量来源!!!!!!

    技能篇

    第六章:自由人的工作生活整理术

    巧用大脑的五个方法,十倍提高个人效能

    1.越高效,越自由

    • 自由职业首先是一种职业,其次才是自由。
    • 事实上,能活得好的自由职业者,往往都是效能达人,用一个小时完成三个小时的任务,才能多出两个小时享受真正的自由。
    • 自由职业者的高效主要体现在三个方面:
      • 时间方面:能做到单位时间创造更多的价值
      • 能力方面:能做到一个人就是一家公司
      • 情绪方面:能做到快速调节降低内耗。
    • 自由职业不是轻松的活儿,它向来都是强者的游戏。

    2.了解大脑的运行机制

    • 心理学研究表明,人类拥有三套负责认知、决策的闹系统:反射脑、思考脑和存储脑
    • 反射脑:
      • 关注当时当下,特点是速度快,在你还没有反应过来的时候,反射脑就已经完成了工作。
      • 反射脑之所以能够左到“即时反应”,很大部分归功于基因记忆。
      • 反射脑的快速反应能够保护人类在面临危险或突发情况时,快速做出自保反应。
    • 思考脑:
      • 负责抽象思考,通过逻辑分析、权衡利弊做出长远来看对自己有利的决策和行为。
      • 思考脑工作的时候会消耗大量能量,之所以长时间专注工作一段时间后,很多人会想吃点甜食,就是因为糖是人类大脑主要的能量来源,大脑对葡萄糖的消耗量,比身体任何器官都要多。
      • 思考脑的特点:只能专注一件事
        • 现代人所谓的“一心多用”表面上看起来是同时在做很多事情,实际上思考脑是在A、B、C等多种任务中不断切换,每次切换都会带来能连损耗,导致对信息的接收质量并不好
    • 存储脑:
      • 对接收的各种信息进行整理和存储
      • 记忆过程实际上就是大脑对信息进行有效检索的过程,所以要“过目不忘”就要保证存储脑的工作状态
    • 存储脑和思考脑的相互配合:
      • 当思考脑在工作的时候,存储脑处于休眠状态
      • 一旦思考脑停止工作,存储脑就会开足马力工作
      • 最常见的思考脑休息、存储脑工作就是睡眠时间。而长期失眠所造成的记忆力减退,就是存储脑无法工作的表现。
      • 静心冥想、打个盹儿,都可以促进存储脑的工作

    3.巧用大脑提高效能

    • 方法一:自动驾驶法:“驯服”反射脑
      • 训练自己形成条件反射,定时定点的做固定动作
      • 将日常生活琐事决策从思考脑转移到反射脑自动处理,就可以加快处理速度,每年就可以多出阅读45本书的时间
      • 实践:找到生活中那些可以定时定点做固定动作的事情,然后不断重复直到成为条件反射,就能利用反射脑快速处理,从而提高日常效能
    • 方法二:双脑运转法:一小时用出两小时成效
      • 当反射脑在“自动驾驶”的时候,思考脑就可以趁机做一些思考工作。这样一来就可以在同一时间段完成多项工作,提高时间利用的效率。
      • 由于思考脑喜欢专注、连续性的工作,因此轻量级的内容的选择也有技巧,例如:
        • 排队时间用手机采购日常用品或打亲情电话
        • 早上蹲马桶的时候构思清晨间写作提纲
        • 洗澡的时候思考一些棘手问题
      • <注意>:请一定在保证人身安全的前提下,合理使用双脑运转法
    • 方法三:狩猎法:开足火力,一击即中
      • 如果说方法一、方法二是技巧,那么方法三就是真正的硬功夫!
      • 我们在处理大块重要任务的时候,也需要像猎豹一样全神贯注,开足火力一击即中。
      • 把最困难的工作放在清晨间集中完成的好处:
        • 第一,早上大家还没有开始工作,即使关机也不用担心错过重要的事情
        • 第二,经过一晚上的休息,早上的头脑是最清醒的
        • 第三,在一天刚开始的时候就完成了当天最重要也是最困难的工作,信心会大增,接下来的工作就会觉得很轻松。
      • 不管是职场人还是自由人,在晨间开足思考脑火力,全神贯注投入重要工作都是至关重要的事情。
      • 一个人能否实现个人自由,就看他是否能够每天坚持做点儿能在未来帮助自己的事情。什么叫“帮助未来的自己”?
        • 具体来说就是回答这样一个问题:三年后的你具备什么条件,能够让你有更多从容的选择的机会?为了具备这样的条件,现在你可以开始做点什么?
      • 多数人生活的困局,往往在于安逸的时候没有为未来提前储备,等到需要的时候已经来不及了。
    • 方法四:一休法:聪明休息、更聪明
      • 前三种方法都在讲如何利用反射脑和思考脑的运行特点提高效能。不过一直让大脑高速运转,再强大的大脑也会不堪重负,待机罢工。更何况大脑休息不好,存储脑没有工作的机会,也就无法消化整理大脑接收到的信息,从长远来看反而对提升个人效能不利。
      • 大脑功能是有分区的:每个半球分为前额叶、后额叶、顶叶、颞叶和枕叶,分别负责精神功能、思维功能、体觉功能、听觉功能和视觉功能
    大脑功能分区
    • 说明:
      • 当你在阅读的时候,负责思维和视觉的脑区处于活跃状态
      • 过了一会,你觉得有点累了,合上书本躺在床上休息,闭上眼睛让枕叶区得到了休息,可是你仍在思考刚才阅读的内容,负责思维的后额叶并没有得到休息,所以你还是会觉得很累。
      • 想要快速从阅读消耗中恢复精力,就要切换脑功能区,用激活其他脑区的方法让消耗过度的后额叶得到休息,比如:
        • 做10分钟平板支撑、唱一首歌、看远方的风景等
      • 许多成功人士,多数都有锻炼的习惯
        • 日间的时候,通过运动、小憩快速恢复精力
        • 晚间的时候,则需要通过睡眠激活存储脑的工作,进一步消化整理白天接收到的信息。合理利用睡眠,还能有意识地产生“灵感”。
      • 脑神经科学家猜测人在似睡非睡得过程中,白天活跃得大脑皮层还未被完全抑制,大脑里还留存着深度思考得痕迹。这时候做梦,就很容易梦见跟白天思考内容有关的梦境,甚至是创造性的解决方案!!!
      • 下一次当你用脑过度的时候,与其倒头就睡不如做做眼保健操,活动活动筋骨,照样能恢复精力,还能强身健体。睡觉的时候,试试暗示法,对于一些需要创意的工作也很有帮助
    • 方法五:五分钟线程法:减少损耗,就是增效
      • 思考脑被突发事件中断就类似线程阻塞,看起来就像电脑死机。这时候,如果你的大脑里有类似电脑应对中断情况的程序,就能快速判断,作出反应:
      	if (突发事件能在五分钟内处理掉)
          {
          	X = “马上处理”
          }
          else
          {
          	X = “稍后处理”
          }
      
      • 五分钟线程法的优势在于规则清晰简单,几乎可以立马做出判断。同时,不管什么判断最后都能导出一个明确执行结果
      • 这个方法可以最大限度地减少被中断的时间,更重要的是能稳住情绪。要知道一旦情绪失控,你可能要花好几个小时才能平复。

    无纸化人生,再建一个线上大脑

    1.效率是整理出来的

    • 固定的东西放在固定的位置:
      • 丢东西是小事,重要的是干扰情绪,影响发挥状态
    • 每天花5分钟时间整理:
      • 第一,整理手机:把手机当天收到的重要信息归档
      • 第二,整理随身物品
      • 第三,整理思维,用手机便签软件记录下当天的心得体会,有用的资讯素材收藏到专门的文档里
    • 如果你仔细观察,会发现工作中很多交互确认简易信息的时间是可以不用浪费的,比如:咨询地址、电话或邮箱。
    • 花5分钟时间整理,让工具帮你记忆,你就能杜绝掉很多紧急情况,更能从容地去完成需要大块时间专注的工作。

    2.模板思维,聪明人的懒办法(麻烦现在,方便未来)

    • 机器的记忆是被动的,它只能按照你的设计记住内容,人脑的价值就在于创造规则,好让机器按照你的需要记忆内容。
    • 每当经手一件事情的时候,我都会下意识地问自己:这件事能不能做成模板?这件事用工具软件能不能处理得更快?
    • 模板思维,看起来是复制粘贴的偷懒行为,实际上它需要操作者对事件进行深度分析,才能提炼出可供复制粘贴的内容,即:做事的逻辑。
    • 凡是能用工具软件实现的就不用人力!!!
    • 当你具备“模板思维”能力的时候,你就不再是简单的执行者,而是有全局思维的管理者了。一项能力真正掌握应该以你能传授他人为衡量标准
    • 养成整理的习惯,掌握“模板思维”,配置好工具软件,你一个人就能像一家公司一样运转!!!!!!
    • 对自由人很好的工具:
      • 公众号:你的个人网站、你的职业名片
      • 微信
      • 金数据:做需求资料收集、客户评价反馈、嘉宾资料收集、会议议题征集等都非常方便。
        • <注意>:表单工具只是呈现方式,更重要的是设计表单的瑞吉。不同的题设逻辑,会影响收集到信息的效用
      • 印象笔记:我的线上大脑,记录着我的工作生活的方方面面。
        • 记录是一件非常神奇的事情,只要记录的时间足够长,在某个单点记录的内容足够多,就很容易形成体系
      • 百度网盘:为了避免重要数据丢失,在印象笔记之外,我还搭配使用百度网盘,将一些重要的资料备份到网盘里。
      • 石墨文档:印象笔记、金数据、网盘适用于单点场景,在协作场景中则需要用石墨文档。
    • 我认为企业和组织不应该惧谈“自由人移动办公”,相反应该创造条件让员工具备并发挥这种能力这是未来企业吸引、留住优秀人才的趋势。

    别让情绪成为你的“效率杀手”

    1.打造自由职业需要过情绪关

    • 在有一份能满足温饱收入的工作之余,去探索第二职业是比较稳妥的路径。
    • 明确人生关键词,制订重生年计划,给自己定一个主题学习,用一年的时间持续投入
    • 如果你已经陷入恐惧怎么办?
      • 首先,承认自己的恐惧,恐惧是你的自我保护本能,并不可耻。
      • 其次,理解恐惧是一种感觉,并不代表事实。
      • 最后,要知道实物都有周期,恐惧情绪也不例外,随着时间的推移,投入正向活动,你最终能走出恐惧。
    • 自问自答是我很喜欢的一种缓解负面情绪的方法。假如现在你因为没有收入而觉得恐惧,可以参考以下示例进行练习:
      • 现在你的感受是什么?
        • 答:我感觉很恐惧
      • 什么事情让你恐惧?
        • 答:我没有收入,银行卡里的积蓄在减少,现实没有好转的迹象
      • 你能描述一下这种恐惧带给你的身体感受吗?
        • 答:我感觉胸很闷,心跳加快,但是又动弹不了,像是窒息了一样
      • 像是窒息了一样?听起来像是死亡的恐惧是吗?
        • 答:是的
      • 那你存在真实的生命危险吗?也就是说,你真的会死吗?
        • 答:我想我不会,虽然没有收入让我很恐惧,但是我还不至于死掉。实在不行,我去刷盘子也能挣到钱,不至于饿死
      • 听起来好像情况并没有那么糟糕,对吗?
        • 答:嗯。。。是的
      • 除了刷盘子,还有什么方法可以让你“不至于饿死”呢?
        • 答:跟朋友借钱,回父母家蹭饭、找一份工作、兼职、打零工。。。方法挺多的
      • 没错,你很有方法呢!现在,可以告诉我,你还恐惧吗?
        • 答:没那么恐惧了,只要动起来有事情做就没那么恐惧了
      • 看起来是闲出的毛病咯?
        • 答:哈哈,你真幽默
    • 这个练习方法的要点在于“拨开情绪的迷雾,看到事实的真相”,对于缓解恐惧、焦虑、不自信都有帮助。

    2.管理情绪前,先识别情绪模式

    • 当情绪产生时,想办法调节只能应一时之急,更好的方法是找出你的情绪模式,提前预防或干预。
    • 每天晚上我会在印象笔记的日程表里记录当天的情绪心情,并从0分到10分,给自己的状态打分:
    情绪整理表
    • 持续记录一段时间,你就能捕捉到一些情绪规律的蛛丝马迹。找到这些“情绪地雷”之后,就能制定相应的“情绪降落伞”,达到情绪波动“软着陆”的效果。

    3.如何度过成长过程中的低谷期

    • 其实,负面情绪跟正面情绪一样,都有价值。事实上,当你回顾过去时,你成长最快的时期,往往都在低谷期!
    • 同一层面的问题,不可能在同一层面解决,只有高于他的它的层面才能解决!!!!!!
    • 把困惑你的问题套用这样的句式:“如果我知道我的死期,我还会。。。。。。”,你会发现糨糊一样的逻辑瞬间理清,例如:
      • 如果我知道我的死期,我还会在意一份温饱的工作吗?
      • 如果我知道我的死期,我还会觉得挣得钱不够多吗?
      • 如果我知道我的死期,我还会担心爱上的不是最对的那个人吗?
      • 如果我知道我的死期,我还会担心创业失败吗?
    • 对外来每一分钟的担忧,都是损失掉当下每一分钟的拥有!!!!!!
    • 当你理解生命就是体验的综合,你所厌弃的低谷期是你生命的一部分,那么就无所谓好坏了。接纳它,然后穿越它。我想活着,又不被生活所役,大概就是这样的状态吧。

    如何练就“好运体质”

    1.你已经很努力,为什么还没有逆袭

    • 制约理论,解释当前系统中存在明显制约条件时,在制约条件之外的投入都是浪费资源。
    • 不同成长阶段运用的系统还不一样,“钻石人生图”在探索自我、积蓄力量的时候使用(第四章)。而当你已经基本完成个人定位,开始进入加速发展时期的时候,就需要用到另一个系统————黄金五角星
    黄金五角星
    • 说明:
      • 个人竞争力:指个人知识、能力方面的综合实力
      • 个人效能:指对时间的运用效率
      • 财产:指能由你自由支配的资金或产业
      • 人脉:指有助于个人成长的人际关系
      • 健康:指身体素质
    • 就你目前的人生状态而言,五个角的贡献值分别是多少?按照0~10分给自己评分。贡献值,指的是该模块在你个人成长中起了多大作用。
      • 对于大部分上进好学的普通青年而言,健康、个人竞争力、个人效能的贡献值都不会太低,低分多数落在人脉和财产的两个“角”
      • 这就是拉低个人加速成长系统的两个制约条件!!!!!!
    • 综上,根据高德拉特博士的“制约理论”,在人脉和财产两个制约条件之外的投入都是浪费资源。
    • 既然是普通青年,想要一夜暴富提升财产贡献值几乎是不可能的,能做的就是做好储蓄,学点理财知识,更重要的突破口在人脉这个“角”。人脉贡献值每提高一份,整个“黄金五角星”的势能就会大幅提升,这才是突破个人加速期的正确姿势。

    2,你认识再多牛人,跟你有关系吗

    • 真正的人脉关系,是建立在价值对等之上的。注意,价值对等不是说身价对等!!!
      • 也许你现在的年收入只有5万元,但是你有50万的胆识和能力,就可以跟年入500万的牛人合作50万元的生意,此时价值对等合作关系就能建立。
      • 经由合作,你得以近身学习年入500万的人的思考、做事方式,然后你就有达成500万合作的胆识和能力。
      • 然后得以跟年收入50000万的牛人合作,而你的收入也从最初的年入5万元,变成了年入50万。
    • 在职场中,想要收获高质量的人脉关系,就不能老想着别人为你做什么,而要多想想你能为别人做什么,

    3.如何练就“好运体质”

    • 好运体质的三个锦囊:
      • 锦囊一:雪中送炭,没有人会不喜欢能在你困难时雪中送炭的朋友
      • 锦囊二:锦上添花。如果我是朋友中过的最好的那个人,说明我的圈子有问题!
      • 锦囊三:成人之美,大家都希望自己身边能多一些乐于助人的人,都乐意跟这样的人交朋友、搞事情、掏心窝

    未来的学习模式,是学徒制的回归

    1.未来10年,真正应该学习的是什么

    • 同样是讲营销,一堂《我是如何在30天内卖光10套房》的课程会比《营销心理学》更受欢迎,前者是实战后的经验,后者是理论上的知识。
    • 与其说人们是在为知识付费,不如说是在为经验付费。
    • 现代世界变得越来越快,也越来越不确定。面对不确定性,有多少确定性的知识就显得没那么重要了。
      • 硅谷知名孵化器YCombinator(YC)在遴选创业项目时表示:比起有没有斯坦福商学院学位,我们更感兴趣的是你有没有经历过真实的创业。
    • 当专门提供知识的学校不能满足学生获取经验的需求时,学生就只能另谋出路,把学费交给有经验的人,这就是学徒制的回归。

    2.城市游学,把城市变成你的私人定制教室

    • 师傅不会自己找上门,想要学到宝贵的经验,只有主动走出去才有机会。只要有场景的地方,就能学到经验!!!
      • 比如:去宜家去学习家居设计,去沃尔玛去学习商品陈列,去星巴克去学习品牌营销
      • 这种学习方式的优势是场景感强,可以直接从商家花费了大量投入的最终成果中快速捕捉要点!!
      • 二劣势在于对学习者的观察、分析能力要求比较高,吸收到经验比较零散。
    • 如果想要有人指导你学习,线下社群活动是个好地方。啡信机构

    3.一些值得关注的社群

    • 折书帮(全国性社群,搜索公众号“折书帮”):一个专注阅读的社群,支持成员把书中的知识转化为自己的能力,让知识为自己所用
    • 闺蜜力量Bestie(全国性社群,搜索公众号“闺蜜力量Bestie”):是支持女性轻创业的O2O教育平台,致力于帮助女性用优势开启个人事业、打造多元收入,用实践的方式提升商业力。
    • EnglishUp放肆说(区域性社群,搜索公众号“EnglishUp放肆说”):一个为个人和家庭提供地道美语发音的英语学习社群,你可以在这里通过优质线下精品小班、线下口语实践活动、线上纠音训练营等方式实现“自信开口说英语”的梦想
    • 广州行动派伙伴圈(区域性社群,搜索公众号“广州行动派伙伴圈”):为爱学习、分享的朋友提供交流、学习、成长的圈子,每月不定期矩形读书会和城市行活动
    • 头马俱乐部(全国性社群,网址“Toastmasters.org”):为会员提供一个安全的、互助的、有反馈的个人成长环境,系统地帮助个人提升沟通表达能力和领导力,从而实现自信的全面进步。
    • 笔记侠(全国性社群,搜索公众号“笔记侠”):是中国最大的新商业知识干货笔记共享平台,目前为70万企业决策及管理层提供最前沿的全球商业演讲、顶尖商学院课程、经典商业书籍、深度专栏等学习笔记,深受全国侠客们的称赞和喜爱。
    • WorkFace全球创业者社群成都分部(全国性社群,搜索公众号“WorkFace成都”):倡导“所有人服务所有人、所有人向所有人学习、所有人支持所有人”的“三所有”价值观,建立创业者与创业者之间的联结。

    第七章:新手如何开启个人事业

    主题式学习,互联网时代学习的正确姿势

    1.毕业后,该如何学习

    • 职场中,考试不再是你评优的唯一标准,而是你的入场券。
    • 学生的任务是熟练地掌握知识,而社会人的任务则是熟练地解决问题。
    • 目标不同,决定了形式的差异:
      • 学生为了熟练掌握知识,需要的是理解、记忆、举一反三,最后给出问题的答案
      • 社会人为了熟练地解决问题,需要的是分析、拆解、各个击破,最后提出正确的问题。
    • 所以,社会人的学习实际上是一个提出问题、验证答案的过程!!!
    不同的学习方式

    2.社会人的学习,始于提问

    • 历史上,凡是在各自领域取得突出成就的人,无一不是善于提问的人
    • 名人名言:
      • 正是问题激发我们去学习,去实践,去观察。————鲍伯尔(维也纳自然科学和社会科学家)
      • 我没有什么特殊的才能,不过是喜欢寻根刨底地追究问题罢了。————爱因斯坦
      • 提出正确的问题,往往等于解决了问题的大半。————海森堡(德国著名物理学家)
      • 生活的智慧大概就在于逢事都问个为什么。————巴尔扎克(法国著名小说家)
      • 创造始于问题有了问题才会思考有了思考,才有解决问题的方法,才有找到独立思路的可能。————陶行知(中国著名教育家)
    • 因此,社会人的学习,第一步就是要学习如何提问。

    3.社会人的学习,以解决问题为导向

    • 有了正确的问题之后,第二步就需要有解决问题的思路————思维模型
    • 我自己比较喜欢的事立体式思维,从不同角度去思考同一个问题。
    • 人们总是倾向于接受跟自己相同的观点,而对于不同的观点则会选择性屏蔽,所以刻意让自己看到事情的不同面向,更有利于社会人解决问题。
    • 社会人的学习事以解决问题为导向的,而问题的解决需要的事从认知到行动的贯穿,没有核心的单点技能学习就像没有根的树枝事没有意义的。相反,如果你的根系很发达,你并不需要有很多树枝,也能稳稳地生长在这个世界上。

    为什么你一直努力地“穷”着

    1.一切不以输出为目标的成长都是自嗨

    • 成长一定要跟金钱挂钩吗?很抱歉。。。
      • 如果你不是等着继承几千万的富二代,如果你还需要工作来换取生活的资本,那么你的成长就必须跟金钱挂钩。
    • 金钱,或者说货币,本质上事价值的体现。
    • 如果你想增加收入,让社会支付你5万元而不是5000元的薪酬,你就需要拿出更多的价值来交换。这跟你是否努力学习没有关系,而是跟你的学习是否能创造价值有关系。
    • 企业家之所以比普通人拥有更多的财富,就是因为企业家单位时间为社会创造的价值更多。“创造价值”已经融入了企业家的血液里,他们无时无刻不在想着为他人创造价值,这已经成了企业家的天性。
    • 对于想要获得财富成长的年轻人,在努力学习的同时,还需要努力学习为他人创造价值。不要让努力本身迷惑自己,只有当你努力能为这个世界创造美好的未来时,你的努力才是有效的,也才能带来生活的真实改变。

    2.有价值的输出倒逼有价值的输入

    3.找到自己舒服的方式输出

    • 每个人有自己的优势,用自己的优势方式输出更容易产生价值,也更容易坚持。(优势详见第四章)
    • 在探索适合自己输出方式的过程中,免不了会精力一番曲折,不过一切都是值得的。

    如何快速学会一项新技能

    1.技能学习中的“二八定律”

    • 在个人成长中,80%的成长来自作对了20%的事情。比如,明确了自己的人生关键词,进而有方向、有重点地快速发展。
    • 在开启个人事业前期,没有太多外力可以借助,常常需要一个人分饰多种角色,完成多种任务。
    • 因为人的时间有限,不可能样样从零开始自学,这就需要分清哪些技能是需要深入钻研达到专业水平的,哪些技能只需要基本掌握就可以了!!!!!!
    • 对于只需要基本掌握的技能,20个小时的有效投入足以让小白到业余水平,覆盖80%的运用场景。
      • 关键在于着20个小时应该投入到哪里?我的经验是,投入到“二八定律”中那些能带来最大效益的20%的部分

    2.黄金圈法则(识别那20%重要的部分)

    • 黄金圈法则————知名营销专家西蒙·斯涅克,他认为伟大的领袖之所以能激励出伟大的行动,是因为他们遵循“为什么——如何做——做什么”的言行方式。
    黄金圈法则
    • 一个例子:苹果电脑是如何影响他人决策的
      • 通常电脑公司在介绍自家产品时,这样说:我们做最棒的电脑,设计精美,使用简单,界面友好,你想要买一台吗?
      • 而苹果公司是这样表达的:
        • 我们做的每一件事,都是为了创新和突破。我们坚信应该以不同的方式思考。
        • 我们挑战现状的方式是通过产品设计得十分精美,使用简单,界面友好。
        • 我们知识在这个过程中做出了最棒的电脑,你想要买一台吗?
      • 前者重在强调产品有什么功能和优势,而后者是站在意义层面跟消费者沟通,赋予消费以意义感————你买的不只是苹果电脑,还是“买”一种追求完美、突破创新得精神。
      • 苹果公司搞清楚了20%得重要部分————价值比功能更重要————进而撬动了消费者80%得购买意愿

    3.关注意义,而不是关注形式

    4.向高手学习

    5.慢思考,快行动

    • 人容易沉溺于行动中得快感,觉得只要有事做就是努力。殊不知如果方向错了,停下来就是进步。
    • 在行动和思考之间,需要看情况分阶段考量。假如一个决定会影响你未来三个月得走向,就最好多花一点时间去思考,多问自己几个“为什么”,花80%得时间想清楚20%得事情。一旦想清楚之后,就快速行动起来,不要追求完美,而是在过程中去完善!!!!!!!!!!!!!!

    技能交换,开启你的个人事业

    1.技能交换,低风险获得市场经验

    • 对个人而言,开启个人事业相当于是一次个人创业。
    • 创业中会涉及得产品、渠道、团队、资金等问题,在个人事业中也会出现。
    • 通过前五章得内容学习,你大致有了个人事业得方向,接下来就需要快速投入世行校准方向!
    • 事实上,个人事业由于推出得产品/服务是定制化得,更需要在市场的反馈中不断优化。
      • 在小范围内让目标客户体验,然后测试效果迭代升级,这在互联网行业中称为“内测”,是每一款产品都必须精力得过程!!
      • 想要打造优质的个人事业产品/服务,也需要经过“内测”
      • 免费内测不实际,也不利于个人事业者得长远发展。不妨尝试“技能交换”得方式,用个人事业产品/服务交换客户得优势技能。这样既能测试产品效果,收获案例经验,还能学习到对方的优势技能,对个人事业早期探索者来说是非常有价值的!!!

    2.个人事业如何定价

    • 我的经验是:
      • 定价 = 最近一份全职工作的时薪 × 完成个人服务所需要耗费的时间 × 3
      • 示例:
        • 你最近一份全职工作月薪是4000元,按照每个月工作22天,每天工作8小时计算,时薪就是 4000 ÷ (22×8) = 23元/小时
        • 写一篇文案从构思、写作,再到排版大约需要6小时,那么撰写一篇文案的市场价大约就是 23×6×3 = 414元。
      • 为什么要乘以 3 呢?
        • 第一,不是每天都有客户,等待时期比较长
        • 第二,定制服务是为每一位客户个性化服务,其价值自然比标准化产品大
      • 通过这个公式也可以看出,个人事业者想要提高收入,要么提高时薪,要么提高效率(第六章),减少时长

    3.个人事业到自由人协作

    • 随着你的个人事业服务趋于成熟,出于增加效益的考虑(即提高时薪或提高效率),就有了组建团队的需要。让更专业的人去做专业的事,不仅能提高整体服务的品质,还能提高效率!!!

    打造个人品牌三步曲

    1.这是个人品牌的时代

    • 当今世界,价格已经不再是消费决策的唯一标准,品牌成了消费者关心的问题,哪怕要为此付出更高的价格。
    • 到了现在,品牌开始拟人化了。消费者会因为喜欢某个人,而选择TA所推荐的产品,比如李佳奇、威雅等
    • 对于普通人来说,是机遇也是挑战:
      • 机遇是:只要你能在某个领域形成自己的个人品牌,就能辐射一部分受众,搭建自己的个人事业版图。
      • 挑战是:你不能停止成长,这样才能为你的个人品牌注入源源不断的生命力

    2.普通人打造个人品牌的三步曲

    • 个人品牌的定义:指个人拥有的外在形象和内在涵养所传递的独特、鲜明、确定、易被感知的信息集合体。能够展现足以引起群体消费认知或消费模式改变的力量。具有整体性、长期性、稳定性的特性。
    • 我的总结就是:你如何被别人记住、信任和选择?
      • 记住、信任和选择,就是普通人打造个人品牌的三步曲!!!!!!
    • 第一步:记住
      • 个人品牌的打造不是一蹴而就的,第一步就是要让你的受众记住你。
      • “记住”的关键不是不会忘记,而是在特定的场景下能够“想起”!!!!!!
      • 仔细观察商业世界中那些让消费者记住的品牌,常常都是锚定了一个场景让消费者能够想起,例如:
        • 今年过节不受理,收礼只收。。。
        • 怕上火,就喝。。。
      • 相信这品牌广告语不用写完整,你都能自动联想到产品。每次我去吃火锅的时候都担心上火,就会联想到王老吉的广告,进而会选择购买,这就是商家想要达到的目的!
      • 对于个人品牌而言也是如此,要想被人记住,就需要给受众一个场景,将这个场景跟你的产品服务结合起来。一旦受众遇到类似的场景,就会联想到你。
      • 如何找到这样的场景呢?
        • 我的建议是从你自己出发,看看你经验丰富的场景是什么
    • 第二步:信任
      • 当受众记住你的个人品牌标签之后,接下来就需要让受众信任你是“名副其实”的。最直接的表现就是你是不是自己产品服务的受益者。
      • 建立信任最好的方式就是践行你所倡导的东西。
      • 我个人非常不提倡用过度宣传的方式来获取客户的信任,从长远来看,这对个人品牌是极大的伤害。
      • 个人品牌不是靠说出来的,甚至都不是靠做出来的,它是通过你生活的状态传递出来的!!!!真正的品牌,其实就是做真实的自己。
    • 第三步:选择
      • 当受众记住了你,也信任你能提供真实的价值,那么在同类服务中,如何让受众决定选择你呢?
      • 在品牌公司、价格、品质、售后服务等因素都是影响消费者决策的原因。
      • 而在个人品牌领域,品牌拟人化到一个人身上,很难单独从价格、品质、售后服务方面去区分比较,更多的时候从何成了一种感觉:“你的经历和我好像,我想成为你的感觉”,场景让人想起你,经历让人共鸣。

    3.打卡小动作,品牌大价值

    • 朋友圈通常是开启个人事业的第一战,如何经营好你的朋友圈,对个人品牌打造其实很重要!!!!!!
    • 打卡的确是一种打造个人品牌的好方法,不过也需要打开姿势的正确。
    • 打卡需要立体感,用重生四维度的方式打卡,可以很好地传递你的个人品牌价值,它包含五个关键要素:
      • 要素一:话题 #用一年时间重生# 第 × 年 ××× 天
        • 第一句话这样说,使得话题本身传递出非常强烈的价值观信息。
        • “第 × 年 ××× 天”能传递出滴水穿石的坚持新年,这不是短期的即兴做法,而是贯穿人生的一种生活理念。
      • 要素二:人生关键词
        • 写出自己的人生关键词,一方面是加深自己的记忆,检视自己的生活是否有围绕人生关键词在投入精力
        • 另一方面,也有非常鲜明的个人特色,相当于告诉别人你想成为什么样的人,你在朝着什么方向努力,有相同价值观的人会一眼被你的关键词击中,产生奇妙的链接
      • 要素三:输入、输出、开源、固本四维度日总结
        • 四维度的总结能立体地呈现你的生活和追求,朋友圈读者会看到更加真实的你,同时也是有故事的你。
        • 在些四维度总结的时候,最好有一些故事性,避免单纯地罗列。
      • 要素四:一句话小结
        • 这句话最好简洁有力且富有哲理,其作用相当于文章的金句
        • 如果原创有难度,可以借用一些代表你心情的名言名句。
      • 要素五:精美配图
        • 在阅读朋友圈的时候,图片比文字更有吸引力
        • 可以选择一些精美网络图片作为配图。
        • 如果可以的花,最好用自己当天拍到的具有生活气息的照片。
        • 在构图、意境、排列上稍微用心,让图片更有美感,也更容易吸引人的眼球
    打卡示范

    推荐书籍

    • 《拆掉思维的墙》:关于职业发展的课程
    • 《你的生命有什么可能》
    • 《跃迁》
    • 《低学历的五大师》:在所有关注的问题之中,应该注意将精力集中放在最重要的那一部分,这个道理从小到各个阶段的人生规划,大到一个国家的治理都是适用的。比如:
      • 二十几岁的年轻人最重要的问题是学习,那么就应该把精力放在如何学习之上。
      • 三十几岁的青年人最重要的问题是立业,那么就应该将精力放在立什么业,如何立业之上。
    • 《牧羊少年奇幻之旅》:当你走向一个正确方向的时候,一开始你会有新手的运气,开局会很顺利。但是,这样的好运不会持续下去,后面将会有各种挑战来考验你是否有远征者的勇气。
    • 马斯洛需求层次理论:人在满足了基本胜利需求、完全需求后,就会寻求更高层次的精神需求、自我实现需求
    • 电影:《彗星来的那一夜》,关于平行时空假设的经典电影
    • 《牧羊少年奇幻之旅》,也叫《炼金术士》,用隐喻的方式几乎讲完了人生所有的股市:要不要追寻梦想?如何开始第一步?追梦过程中你会遭遇些什么?如何面对选择、诱惑和挫折?最终你的宝藏是什么?
    • 《Evernote超效率数字笔记》
    • 以色列管理大师艾里·高德拉特在他的畅销书《目标》中提出了“制约理论”
    • 《营销心理学》,《我是如何在30天内卖光10套房》
    • 《金字塔原理》,关于表达逻辑得书籍
    展开全文
  • 近期总结一一些面试题 都是企业的面试题笔记题 感觉薪资10k下的都会出笔试题 ...同时分享一个自己录制的CSS3动画特效经典案例【推荐教程】--后期会更新vue框架 微信小程序等内容。 https://ke.qq.com/cou...

    近期总结一一些面试题 都是企业的面试题笔记题

    感觉薪资10k下的都会出笔试题   

    特别高的薪资都是直接技术面试或者是 现场编程 

    总结很多人的面试题,后期会对于单个知识点再说笔记详细讲解。

    最新Vue面试题网址:2021年 Vue经典面试题 -- 必问知识点 --(包含答案)_xm1037782843的博客-CSDN博客_vue面试题

    敬请关注公众 :包含全套 Vue 最新面试题  js最近面试题 等大量前端知识技术。

     

    部分都是百度的答案,不是特全面的,可以自己找下

    同时分享一个自己录制的CSS3动画特效经典案例【推荐教程】--后期会更新vue框架 微信小程序等内容。

    最近录制的ajax从基础到实战的视频,包含原生ajax  jquery的ajax 以及ajax接口获取数据等

    Ajax前端开发、项目实战、从零基础到精通、接口数据调用-学习视频教程-腾讯课堂

    红色为常见面试题

    =============================================================

    前端面试题: 

    1. 一个200*200的div在不同分辨率屏幕上下左右居中,用css实现

    <div style="width:500px;height:500px;border:1px solid green;display:flex;justify-content:center;align-items:center;">
      <div style="">
        上下左右居中
      </div>
    </div>

    2. 写一个左中右布局占满屏幕,其中左右两块是固定宽度200 ,中间自适应宽,要求先加载中间块,请写出结构及样式:

    <div id="left">我是左边</div>
        <div id="center">我是中间</div>
        <div id="right">我是右边</div>
    
    html,body{ margin: 0px;width: 100%; } 
    #left,#right{width: 200px;height: 200px;background-color: aqua;
        position: absolute;}
        #left{left: 0;top:0;}
        #right{right: 0;top:0;}
        #center{margin: 0 200px;background-color: blue;height: 200px;}

    或者利用弹性盒子

        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            html,
            body {
                height: 100%;
            }
    
            body {
                display: flex;
            }
    
            .left {
                width: 100px;
                background-color: rgb(199, 170, 223);
            }
    
            .center {
                background-color: rgb(151, 228, 148);
                flex: 1;
            }
    
            .right {
                width: 100px;
                background-color: rgb(199, 170, 223);
    
    
            }
        </style>
    
    <body>
        <div class="left">left</div>
        <div class="center">center</div>
        <div class="right">right</div>
    </body>
    

    3. 阐述清楚浮动的几种方式(常见问题)

    1.父级div定义 height

    原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
    优点:简单、代码少、容易掌握
    缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

    2.父级div定义 overflow:hidden

    原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
    优点:简单、代码少、浏览器支持好

    4. 结尾处加空div标签 clear:both

    原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
    优点:简单、代码少、浏览器支持好、不容易出现怪问题

    缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好

    5. 解释css sprites ,如何使用?

    CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。

    CSS Sprites为一些大型的网站节约了带宽,让提高了用户的加载速度和用户体验,不需要加载更多的图片

    6. 如何用原生js给一个按钮绑定两个onclick事件?

    Var  btn=document.getElementById(‘btn’);

    //事件监听 绑定多个事件

    var btn4 = document.getElementById("btn4");

    btn4.addEventListener("click",hello1);

    btn4.addEventListener("click",hello2);

    function hello1(){

     alert("hello 1");

    }

    function hello2(){

     alert("hello 2");

    }

    7. 拖拽会用到哪些事件

    · dragstart:拖拽开始时在被拖拽元素上触发此事件,监听器需要设置拖拽所需数据,从操作系统拖拽文件到浏览器时不触发此事件.

    · dragenter:拖拽鼠标进入元素时在该元素上触发,用于给拖放元素设置视觉反馈,如高亮

    · dragover:拖拽时鼠标在目标元素上移动时触发.监听器通过阻止浏览器默认行为设置元素为可拖放元素.

    · dragleave:拖拽时鼠标移出目标元素时在目标元素上触发.此时监听器可以取消掉前面设置的视觉效果.

    · drag:拖拽期间在被拖拽元素上连续触发

    · drop:鼠标在拖放目标上释放时,在拖放目标上触发.此时监听器需要收集数据并且执行所需操作.如果是从操作系统拖放文件到浏览器,需要取消浏览器默认行为.

    · dragend:鼠标在拖放目标上释放时,在拖拽元素上触发.将元素从浏览器拖放到操作系统时不会触发此事件.

    8. 请列举jquery中的选择器:

    9. Javascript中的定时器有哪些?他们的区别及用法是什么?

    setTimeout 只执行一次
    setInterval 会一直重复执行

    9.请描述一下 cookies sessionStorage和localstorage区别

    相同点:都存储在客户端
    不同点:1.存储大小

    · cookie数据大小不能超过4k。

    · sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

    2.有效时间

    · localStorage    存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

    · sessionStorage  数据在当前浏览器窗口关闭后自动删除。

    · cookie          设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

    3. 数据与服务器之间的交互方式

    · cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端

    · sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

    10.计算一个数组arr所有元素的和

    var arr1=[1,2,3,4,5,6,7,8,9];

    var sum1=0;

    for (var i=0;i<=arr1.length;i++) {

    if (typeof arr1[i]=="number") {

    sum1+=arr1[i];

    }

    }

    document.write(sum1);

    //====================================

    function sum2(arr){

    var all=0;

    for (var i=0;i<arr.length;i++) {

    if (typeof arr[i]=="number") {

    all+=arr[i];

    }

    }

    return all;

    }

    document.write(sum2([1,2,3,4]));

    11.编写一个方法去掉数组里面 重复的内容  var arr=[1,2,3,4,5,1,2,3]

    一个数组去重的简单实现

     

    var arr = ['abc','abcd','sss','2','d','t','2','ss','f','22','d'];

    //定义一个新的数组

    var s = [];

    //遍历数组

    for(var i = 0;i<arr.length;i++){

        if(s.indexOf(arr[i]) == -1){  //判断在s数组中是否存在,不存在则push到s数组中

            s.push(arr[i]);

        }

    }

    console.log(s);

    //输出结果:["abc", "abcd", "sss", "2", "d", "t", "ss", "f", "22"]

    方法二:用sort()  然后相邻比较也可以实现

    12.document.write和innerHTML的区别:

    document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。

    innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。

    innerHTML将内容写入某个DOM节点,不会导致页面全部重绘

     

    innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

    13.ajax的步骤

    什么是ajax?

    ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页。

    如何使用ajax?

    第一步,创建xmlhttprequest对象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest对象用来和服务器交换数据。

    var xhttp;

    if (window.XMLHttpRequest) {

    //现代主流浏览器

    xhttp = new XMLHttpRequest();

    } else {

    // 针对浏览器,比如IE5或IE6

    xhttp = new ActiveXObject("Microsoft.XMLHTTP");

    }

    第二步,使用xmlhttprequest对象的open()和send()方法发送资源请求给服务器。

    第三步,使用xmlhttprequest对象的responseText或responseXML属性获得服务器的响应。

    第四步,onreadystatechange函数,当发送请求到服务器,我们想要服务器响应执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readyState发生改变都会触发onreadystatechange函数

    14.xml和json的区别,请用四个词语来形容

    ·  JSON相对于XML来讲,数据的体积小,传递的速度更快些

    ·  JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互

    ·  XML对数据描述性比较好;

    ·  JSON的速度要远远快于XML

     

    15.清楚浮动的方法?(多次出现在面试题)

    1.父级div定义 height
    原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
    优点:简单、代码少、容易掌握

    缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

    2,结尾处加空div标签 clear:both

    原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
    优点:简单、代码少、浏览器支持好、不容易出现怪问题
    缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好
    3,父级div定义 伪类:after 和 zoom

    原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
    优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)
    缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持
    4,父级div定义 overflow:hidden

    原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
    优点:简单、代码少、浏览器支持好
    缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。

     

    16.box-sizing常用的属性有哪些?分别有什么作用?

    属性值

    · box-sizing:content-box

    · box-sizing:border-box

    · box-sizing:inherit

     

    content-box

    · 这是box-sizing的默认属性值

    · 是CSS2.1中规定的宽度高度的显示行为

    · 在CSS中定义的宽度和高度就对应到元素的内容框

    · 在CSS中定义的宽度和高度之外绘制元素的内边距和边框

     

    border-box

    · 在CSS中微元素设定的宽度和高度就决定了元素的边框盒

    · 即为元素在设置内边距和边框是在已经设定好的宽度和高度之内进行绘制

    · CSS中设定的宽度和高度减去边框和内间距才能得到元素内容所占的实际宽度和高度

    (Q1)box-sizing: content-box|border-box|inherit;
    (Q2)content-box:宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
    border-box:元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。

     

    17.css选择器有哪些,选择器的权重的优先级

    选择器类型

    1、ID  #id

    2、class  .class

    3、标签  p

    4、通用  *

    5、属性  [type="text"]

    6、伪类  :hover

    7、伪元素  ::first-line

    8、子选择器、相邻选择器

    三、权重计算规则

    1. 第一等:代表内联样式,如: style=””,权值为1000。

    2. 第二等:代表ID选择器,如:#content,权值为0100。

    3. 第三等:代表类,伪类和属性选择器,如.content,权值为0010。

    4. 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。

    5. 通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。

    6. 继承的样式没有权值。

    18. 块级元素水平垂直居中的方法有哪些(三个方法)

    让div等块级元素水平和垂直都居中,即永远处于屏幕的正中央,当我们做如登录块时非常有用!

     实现一、原理:要让div等块级元素水平和垂直居中,必需知道该div等块级元素的宽度和高度,然后设置位置为绝对位置,距离页面窗口左边框和上边框的距离设置为50%,这个50%就是指页面窗口的宽度和高度的50%,最后将该div等块级元素分别左移和上移,左移和上移的大小就是该div等块级元素宽度和高度的一半。

       CSS代码:

    .mycss{ 

       width:300px;  

       height:200px;  

       position:absolute;  

       left:50%;  

       top:50%;  

       margin:-100px 0 0 -150px }

     实现二原理:利用CSS的margin设置为auto让浏览器自己帮我们水平和垂直居中。

       CSS代码:

    .mycss{

        position: absolute;

        left: 0px;

        right: 0;

        top: 0;

        bottom: 0;

        margin: auto;

        height: 200px;

        width: 300px;

    }

    jQuery实现水平和垂直居中

     原理:jQuery实现水平和垂直居中的原理就是通过jQuery设置div等块级元素的CSS,获取div等块级元素的左、上的边距偏移量,边距偏移量的算法就是用页面窗口 的宽度减去该div等块级元素的宽度,得到的值再除以2即左偏移量,右偏移量算法相同。注意div等块级元素的CSS设置要在resize()方法中完成,就是每次改变窗口大 小时,都要执行设置div等块级元素的CSS。

    jquery代码:

    $(window).resize(function(){

        $(".myblock").css({

            position: "absolute",

            left: ($(window).width() - $(".myblock").outerWidth())/2,

            top: ($(window).height() - $(".myblock").outerHeight())/2     });        

    });

    此外在页面载入时,就需要调用resize()方法

    $(function(){

        $(window).resize();

    });

     

    19.三个盒子,左右定宽,中间自适应有几种方法

    第一种:左右侧采用浮动 中间采用margin-left 和 margin-right 方法。

    代码如下:

    <div style="width:100%; margin:0 auto;"> 

     

           <div style="width:200px; float:right; background-color:#960">这是右侧的内容 固定宽度</div>

     

           <div style="width:150px; float:left; background:#6FF">这是左侧的内容 固定宽度</div>

     

           <div style="margin-left:150px;margin-right:200px; background-color:#9F3">中间内容,自适应宽度</div>

     

        </div>

    第二种:左右两侧采用绝对定位 中间同样采用margin-left margin-right方法:

     

    第三种负的margin

    使用这种方法就稍微复杂了一些了,使用的是负的margin值,而且html标签也增加了,先来看其代码吧:

    <div id="main">

     <div id="mainContainer">main content</div></div><div id="left">

     <div id="leftContainer" class="inner">left content</div></div><div id="right">

     <div id="rightContainer" class="inner">right</div></div>

    #main {

     float: left;

     width: 100%;

    }

    #mainContainer {

     margin: 0 230px;

     height: 200px;

     background: green;

    }

    #left {

     float: left;

     margin-left: -100%;

     width: 230px} 

    #right {

     float: left;

     margin-left: -230px;

     width: 230px;

    } 

    #left .inner,

    #right .inner {

     background: orange;

     margin: 0 10px;

     height: 200px;

    }

    20.js有几种数据类型,其中基本数据类型有哪些

    五种基本类型: Undefined、Null、Boolean、Number和String。

    1中复杂的数据类型————Object,Object本质上是由一组无序的名值对组成的。

    Object、Array和Function则属于引用类型

     

    21.undefined 和 null 区别

     

    null: Null类型,代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。

    undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。

    null是javascript的关键字,可以认为是对象类型,它是一个空对象指针,和其它语言一样都是代表“空值”,不过 undefined 却是javascript才有的。undefined是在ECMAScript第三版引入的,为了区分空指针对象和未初始化的变量,它是一个预定义的全局变量。没有返回值的函数返回为undefined,没有实参的形参也是undefined。

     

    javaScript权威指南: null 和 undefined 都表示“值的空缺”,你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。

    22.http 和 https 有何区别?如何灵活使用?

     

    http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。

    https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份


    23.常见的HTTP状态码

    2开头 (请求成功)表示成功处理了请求的状态代码。

    200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 
    201   (已创建)  请求成功并且服务器创建了新的资源。 
    202   (已接受)  服务器已接受请求,但尚未处理。 
    203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。 
    204   (无内容)  服务器成功处理了请求,但没有返回任何内容。 
    205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
    206   (部分内容)  服务器成功处理了部分 GET 请求。

    3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

    300   (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
    301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
    302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
    304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 
    305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 
    307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

    4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。

    400   (错误请求) 服务器不理解请求的语法。 
    401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
    403   (禁止) 服务器拒绝请求。
    404   (未找到) 服务器找不到请求的网页。
    405   (方法禁用) 禁用请求中指定的方法。 
    406   (不接受) 无法使用请求的内容特性响应请求的网页。 
    407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
    408   (请求超时)  服务器等候请求时发生超时。 
    409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 
    410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。 
    411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 
    412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 
    413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 
    414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 
    415   (不支持的媒体类型) 请求的格式不受请求页面的支持。 
    416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 
    417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

    5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

    500   (服务器内部错误)  服务器遇到错误,无法完成请求。 
    501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
    502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
    503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
    504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
    505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

     

     

    24. 如何进行网站性能优化

    1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
    2. 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
      总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。
      前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
      一、页面级优化
    1. JavaScript 压缩和模块打包
    2. 按需加载资源
    3. 在使用 DOM 操作库时用上 array-ids
    4. 缓存
    5. 启用 HTTP/2
    6. 应用性能分析
    7. 使用负载均衡方案
    8. 为了更快的启动时间考虑一下同构
    9. 使用索引加速数据库查询
    10. 使用更快的转译方案
    11. 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染
    12. 用于未来的一个建议:使用 service workers + 流
    13. 图片编码优化

    25. react和vue有哪些不同,说说你对这两个框架的看法

    相同点

    · 都支持服务器端渲染

    · 都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范

    · 数据驱动视图

    · 都有支持native的方案,React的React native,Vue的weex

    不同点

    · React严格上只针对MVC的view层,Vue则是MVVM模式

    · virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制

    · 组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即'all in js'; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,jd写在同一个文件;

    · 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的

    · state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理

    26.什么是mvvm mvc是什么区别 原理

    一、MVC(Model-View-Controller)

    MVC是比较直观的架构模式,用户操作->View(负责接收用户的输入操作)->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)。

    MVC使用非常广泛,比如JavaEE中的SSH框架

     

    三、MVVM(Model-View-ViewModel)

    如果说MVP是对MVC的进一步改进,那么MVVM则是思想的完全变革。它是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应view

    27.px和em的区别

    px表示像素 (计算机屏幕上的一个点:1px = 1/96in),是绝对单位,不会因为其他元素的尺寸变化而变化;

    · 

    · 

    em表示相对于父元素的字体大小。em是相对单位 ,没有一个固定的度量值,而是由其他元素尺寸来决定的相对值。

    28.优雅降级和渐进增强

    渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。

    优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。

    其实渐进增强和优雅降级并非什么新概念,只是旧的概念换了一个新的说法。在传统软件开发中,经常会提到向上兼容向下兼容的概念。渐进增强相当于向上兼容,而优雅降级相当于向下兼容

    29.eval()的作用

    把字符串参数解析成JS代码并运行,并返回执行的结果;

    eval("2+3");//执行加运算,并返回运算值。  

    eval("varage=10");//声明一个age变量  

    eval的作用域

    functiona(){  

    1.  eval("var x=1"); //等效于 var x=1;  

    2.  console.log(x); //输出1  

    3. }  

    4. a();  

    5. console.log(x);//错误 x没有定

    30. JS哪些操作会造成内存泄露

    1)意外的全局变量引起的内存泄露

    function leak(){  

      leak="xxx";//leak成为一个全局变量,不会被回收  

    }

    2)闭包引起的内存泄露

    3)3)没有清理的DOM元素引用

    4)被遗忘的定时器或者回调 5)子元素存在引起的内存泄露

    31. 浏览器缓存有哪些,通常缓存有哪几种

    一、http缓存

    二、websql

    cookie

    localstorage

    sessionstorage

    flash缓存

    32:bootstrap响应式实现的原理

    百分比布局+媒体查询

    33.关于JS事件冒泡与JS事件代理(事件委托)

     事件作为DOM操作重要的一环,需要大家好好理解和运用,今天特意看了一下事件冒泡和事件代理的相关资料,感触颇深,也深感自己的无知不知道多浪费了多少内存,废话不多说进入正题:

    1.事件冒泡:

          通俗易懂的来讲,就是当一个子元素的事件被触发的时候(如onclick事件),该事件会从事件源(被点击的子元素)开始逐级向上传播,触发父级元素的点击事件。

    2.事件委托

        事件委托,首先按字面的意思就能看你出来,是将事件交由别人来执行,再联想到上面讲的事件冒泡,是不是想到了?对,就是将子元素的事件通过冒泡的形式交由父元素来执行。下面经过详细的例子来说明事件委托:

    有可能在开发的时候会遇到这种情况:如导航每一个栏目都要加一个事件,你可能会通过遍历来给每个栏目添加事件:

    事件委托是怎

    1. var ul = document.getElementById('parentUl');  

    2.     ul.οnclick=function (event) {  

    3.       var e = event||window.event,  

    4.               source = e.target || e.srcElement;//target表示在事件冒泡中触发事件的源元素,在IE中是srcElement  

    5.         if(source.nodeName.toLowerCase() == "li"){   //判断只有li触发的才会输出内容  

    6.             alert(source.innerHTML);  

    7.         }  

    8.         stopPropagation(e);                           //阻止继续冒泡  

    9.     };  

    10.     function addElement() {  

    11.         var li = document.createElement('li');  

    12.         li.innerHTML="我是新孩子";  

    13.         ul.appendChild(li);  

    14.     }  

    34. CSS样式覆盖规则

    规则一:由于继承而发生样式冲突时,最近祖先获胜。

    规则二:继承的样式和直接指定的样式冲突时,直接指定的样式获胜

    规则三:直接指定的样式发生冲突时,样式权值高者获胜。

    样式的权值取决于样式的选择器,权值定义如下表。

    CSS选择器

    权值

    标签选择器

    1

    类选择器

    10

    ID选择器

    100

    内联样式

    1000

    伪元素(:first-child等)

    1

    伪类(:link等)

    10

    可以看到,内联样式的权值>>ID选择器>>类选择器>>标签选择器,除此以外,后代选择器的权值为每项权值之和,比如”#nav .current a”的权值为100 + 10 + 1 = 111。

    规则四:样式权值相同时,后者获胜。

    规则五:!important的样式属性不被覆盖。

    !important可以看做是万不得已的时候,打破上述四个规则的”金手指”。如果你一定要采用某个样式属性,而不让它被覆盖的,可以在属性值后加上!important,以规则四的例子为例,”.byline a {color:red !important;}”可以强行使链接显示红色。大多数情况下都可以通过其他方式来控制样式的覆盖,不能滥用!important。

    35. 介绍一下box-sizing属性

    兼容问题 
    首先,box-sizing属性在FireFox中存在兼容问题,所以需要使用-moz-box-sizing做一下兼容。

     

    属性值

    · box-sizing:content-box

    · box-sizing:border-box

    · box-sizing:inherit

     

    content-box

    · 这是box-sizing的默认属性值

    · 是CSS2.1中规定的宽度高度的显示行为

    · 在CSS中定义的宽度和高度就对应到元素的内容框

    · 在CSS中定义的宽度和高度之外绘制元素的内边距和边框

     

    border-box

    · 在CSS中微元素设定的宽度和高度就决定了元素的边框盒

    · 即为元素在设置内边距和边框是在已经设定好的宽度和高度之内进行绘制

    · CSS中设定的宽度和高度减去边框和内间距才能得到元素内容所占的实际宽度和高度

    36. css选择符有哪些?优先级算法如何计算?(常见)

    37. 请简要描述margin重合问题,及解决方式

    1.同向margin的重叠:
    1图片的margin-top与3图片的margin-top发生重叠,2图片的margin-bottom与3图片的margin-bottom发生重叠。这时候重叠之后的margin值由发生重叠两片的最大值决定;如果其中一个出现负值,则由最大的正边距减去绝对值最大的负边距,如果没有最大正边距,则由0减去绝对值最大的负边距。
    解决同向重叠的方法:
    (1)在最外层的div中加入overflow:hidden;zoom:1
    (2)在最外层加入padding:1px;属性
    (3)在最外层加入:border:1px solid #cacbcc;
    2.异向重叠问题:
    1图片的margin-bottom与2图片的margin-top发生重叠,这时候重叠之后的margin值由发生重叠两图片的最大值的决定的。
    解决异向重叠问题:
    float:left(只能解决IE6浏览器中的异向重叠问题,可以解决IE8以上、chorme、firefox、opera下的同向重叠问题)

     

    38:position的值,relative\absolute\fixed分别相对于进行谁定位,有什么区别,什么时候用?

    39.解释下CSS sprites,以及你要如何在页面或网站中使用它。

    CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置

     

    40.什么是闭包,如何使用它,为什么要使用它?

    包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    使用闭包的注意点:

    · 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    · 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

     

    41.请解释JSONP的工作原理,以及它为什么不是真正的AJAX。

    JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。

    AJAX是不跨域的,而JSONP是一个是跨域的,还有就是二者接收参数形式不一样!

    42.请解释一下JavaScript的同源策略。

    在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议, 相同的端口,相同的host,那么我们就可以认为它们是相同的域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

    43.怎样添加、移除、移动、复制、创建和查找节点?

     1)创建新节点

    createDocumentFragment() //创建一个DOM片段
    createElement() //创建一个具体的元素
    createTextNode() //创建一个文本节点

    2)添加、移除、替换、插入
    appendChild() //添加
    removeChild() //移除
    replaceChild() //替换
    insertBefore() //插入

    3)查找
    getElementsByTagName() //通过标签名称
    getElementsByName() //通过元素的Name属性的值
    getElementById() //通过元素Id,唯一性

    44.谈谈垃圾回收机制方式及内存管理

    回收机制方式

    1、定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。

    2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

    3、实例如下:

    function fn1() {

        var obj = {name: 'hanzichi', age: 10};

    }

    function fn2() {

        var obj = {name:'hanzichi', age: 10};

       return obj;

    }var a = fn1();var b = fn2();

    fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

     4、垃圾回收策略:标记清除(较为常用)和引用计数。

    标记清除:

      定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。

      到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

    引用计数:

      定义和用法:引用计数是跟踪记录每个值被引用的次数。

      基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

    45、jQuery的事件委托方法bind 、live、delegate、on之间有什么区别?

    (1)、bind 【jQuery 1.3之前】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:bind(type,[data],function(eventObject));

    特点:

    (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

    (2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

    实例如下:$( "#members li a" ).bind( "click", function( e ) {} );

    (2)、live 【jQuery 1.3之后】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:live(type, [data], fn);

    特点:

    (1)、live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

    (2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

    (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 

    实例如下:$( document ).on( "click", "#members li a", function( e ) {} );

    (3)、delegate 【jQuery 1.4.2中引入】

    定义和用法:将监听事件绑定在就近的父级元素上

    语法:delegate(selector,type,[data],fn)

    特点:

    (1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

    (2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

    实例如下:

    $("#info_table").delegate("td","click",function(){/*显示更多信息*/});

    $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});

    (4)、on 【1.7版本整合了之前的三种方式的新事件绑定机制】

    定义和用法:将监听事件绑定到指定元素上。

    语法:on(type,[selector],[data],fn)

    实例如下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

     总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

    46、px和em的区别

    相同点:px和em都是长度单位;

    异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
    浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

    47、浏览器的内核分别是什么?

    IE: trident内核

    Firefox:gecko内核

    Safari:webkit内核

    Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核

    Chrome:Blink(基于webkit,Google与Opera Software共同开发)

    48、什么叫优雅降级和渐进增强?

    渐进增强 progressive enhancement:
    针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

    优雅降级 graceful degradation:
    一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

    区别:

    a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

    b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

    c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

    49、sessionStorage 、localStorage 和 cookie 之间的区别

     共同点:用于浏览器端存储的缓存数据

    不同点:

    (1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

            web storage,会将数据保存到本地,不会造成宽带浪费;

    (2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

    (3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

            sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

    (4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

    50、浏览器是如何渲染页面的?

    渲染的流程如下:

    1.解析HTML文件,创建DOM树。

       自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。

    2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;

    3.将CSS与DOM合并,构建渲染树(Render Tree)

    4.布局和绘制,重绘(repaint)和重排(reflow)

    51:js的基本数据类型

    JavaScript中有五种基本数据类型,它们分别是:undefined,null,boolean,number,string。

    还有一种复杂数据类型-object。 

    52:事件委托

    事件委托就是利用的DOM事件的事件捕获阶段。把具体dom上发生的事件,委托给更大范围的dom去处理。好比送信员,如果每次都把信件送给每一户,非常繁琐。但是如果交给一个大范围的管理者,比如小区的传达室,那么事情会变得非常简单。事件委托就类似这种原理,我页面中有很多按钮,如果不使用事件委托,我只能在每个按钮上注册事件。非常麻烦。但如果我把事件注册在一个大范围的div(假设所有的按钮都在这个div中),那么我只要注册一次事件,就可以处理所有按钮(只要按钮包含在上述div中)事件的响应了

    53:CSS3新增了很多的属性,下面一起来分析一下新增的一些属性:

    1.CSS3边框:

    · border-radius:CSS3圆角边框。在 CSS2 中添加圆角矩形需要技巧,我们必须为每个圆角使用不同的图片,在 CSS3 中,创建圆角是非常容易的,在 CSS3 中,border-radius 属性用于创建圆角。border:2px solid;

    · box-shadow:CSS3边框阴影。在 CSS3 中,box-shadow 用于向方框添加阴影。box-shadow:10px 10px 5px #888888;

    · border-image:CSS3边框图片。通过 CSS3 的 border-image 属性,您可以使用图片来创建边框。border-image:url(border.png) 30 30 round;

    2.CSS3背景:

    · background-size: 属性规定背景图片的尺寸。在 CSS3 之前,背景图片的尺寸是由图片的实际尺寸决定的。在 CSS3 中,可以规定背景图片的尺寸,这就允许我们在不同的环境中重复使用背景图片。您能够以像素或百分比规定尺寸。如果以百分比规定尺寸,那么尺寸相对于父元素的宽度和高度。

    · background-origin :属性规定背景图片的定位区域。背景图片可以放置于 content-box、padding-box 或 border-box 区域。

    3.CSS3文字效果:

    · text-shadow:在 CSS3 中,text-shadow 可向文本应用阴影。text-shadow:5px 5px 5px #FFFFFF;

    · word-wrap :单词太长的话就可能无法超出某个区域,允许对长单词进行拆分,并换行到下一行:p{word-wrap:break-word;}

    4.CSS3 2D转换:

    transform:通过 CSS3 转换,我们能够对元素进行移动、缩放、转动、拉长或拉伸。

    · translate():元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数:transform:translate(50px,100px);值 translate(50px,100px) 把元素从左侧移动 50 像素,从顶端移动 100 像素。

    · rotate():元素顺时针旋转给定的角度。允许负值,元素将逆时针旋转。transform:rotate(30deg);值 rotate(30deg) 把元素顺时针旋转 30 度。

    · scale():元素的尺寸会增加或减少,根据给定的宽度(X 轴)和高度(Y 轴)参数:transform:scale(2,4);值 scale(2,4) 把宽度转换为原始尺寸的 2 倍,把高度转换为原始高x() 5.CSS3 3D转换:

    · rotateX():元素围绕其 X 轴以给定的度数进行旋转。transform:rotateX(120deg);

    · rotateY():元素围绕其 Y 轴以给定的度数进行旋转。transform:rotateY(120deg);

    6.CSS3 过渡:当元素从一种样式变换为另一种样式时为元素添加效果。

    7.CSS3动画:通过 CSS3,我们能够创建动画,这可以在许多网页中取代动画图片、Flash 动画以及 JavaScript。

    8.CSS3多列:

    · column-count:属性规定元素应该被分隔的列数。

    · column-gap:属性规定列之间的间隔。

    · column-rule :属性设置列之间的宽度、样式和颜色规则。

    9.CSS3用户界面:

    · resize:属性规定是否可由用户调整元素尺寸。

    · box-sizing:属性允许您以确切的方式定义适应某个区域的具体内容。

    · outline-offset :属性对轮廓进行偏移,并在超出边框边缘的位置绘制轮廓。

    54:从输入url到显示页面,都经历了什么

    第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。

    第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。

    第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址。
    第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
    第五步:重复第四步,直到找到正确的纪录

    2种解释:

    一般会经历以下几个过程:

    1、首先,在浏览器地址栏中输入url

    2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

    3、在发送http请求前,需要域名解析(DNS解析)(DNS(域名系统,Domain Name System)是互联网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住IP地址。),解析获取相应的IP地址。

    4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手(TCP即传输控制协议。TCP连接是互联网连接协议集的一种。)

    5、握手成功后,浏览器向服务器发送http请求,请求数据包

    6、服务器处理收到的请求,将数据返回至浏览器

    7、浏览器收到HTTP响应

    8、读取页面内容,浏览器渲染,解析html源码

    9、生成Dom树、解析css样式、js交互

    10、客户端和服务器交互

    11、ajax查询

    55:对<meta></meta>标签有什么理解

    什么是meta标签?

    引自下W3school的定义说明一下。

    元数据(metadata)是关于数据的信息。

    标签提供关于 HTML 文档的元数据。元数据不会显示在页面上,但是对于机器是可读的。

    典型的情况是,meta 元素被用于规定页面的描述、关键词、文档的作者、最后修改时间以及其他元数据。

    标签始终位于 head 元素中。

    元数据可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。

    其实对上面的概念简单总结下就是:<meta> 标签提供关于 HTML 文档的元数据。它不会显示在页面上,但是对于机器是可读的。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。

    meta的作用

    meta里的数据是供机器解读的,告诉机器该如何解析这个页面,还有一个用途是可以添加服务器发送到浏览器的http头部内容

    56:new操作符到底到了什么

    先看代码

    [javascript] view plain copy

    1. var Func=function(){  

    2. };  

    3. var func=new Func ();  

    new共经过了4几个阶段

    1、创建一个空对象

    [javascript] view plain copy

    1. varobj=new Object();  

    2、设置原型链

    [javascript] view plain copy

    1. obj.__proto__= Func.prototype;  

    3、让Func中的this指向obj,并执行Func的函数体。

    [javascript] view plain copy

    1. var result =Func.call(obj);  

    4、判断Func的返回值类型:

    如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。

    [javascript] view plain copy

    1. if (typeof(result) == "object"){  

    2.   func=result;  

    3. }  

    4. else{  

    5.     func=obj;;  

    6. }  

    57:h5新特性

    HTML5新特性 —— 新特性
    (1)新的语义标签和属性
    (2)表单新特性
    (3)视频和音频
    (4)Canvas绘图
    (5)SVG绘图
    (6)地理定位
    (7)拖放API
    58:vue的生命周期

     

     

    58:请写出你对闭包的理解,并列出简单的理解

    使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

    闭包有三个特性:

    1.函数嵌套函数 

    2.函数内部可以引用外部的参数和变量 

    3.参数和变量不会被垃圾回收机制回收

     

    59:display none visibility hidden区别?

    1.display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;

    2.使用visibility:hidden比display:none性能上要好,display:none切换显示时visibility,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),而visibility切换是否显示时则不会引起回流。

    60:JavaScript中如何检测一个变量是一个String类型?请写出函数实现

    typeof(obj) === "string"

    typeof obj === "string"

    obj.constructor === String

    61:如何理解闭包?

    1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。

    2、表现形式:使函数外部能够调用函数内部定义的变量。

    3、实例如下:

    (1)、根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,没有就返回undefined。这里明显count 是函数内部的flag2 的那个count 。

    var count=10;   //全局作用域 标记为flag1function add(){

        var count=0;    //函数全局作用域 标记为flag2

        return function(){

            count+=1;   //函数的内部作用域        alert(count);

        }

    }var s = add()

    s();//输出1

    s();//输出2

    4、变量的作用域

    要理解闭包,首先必须理解Javascript特殊的变量作用域。

    变量的作用域分类:全局变量和局部变量。

    特点:

    1、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。

    2、函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

     5、使用闭包的注意点

    1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    62:谈谈垃圾回收机制方式及内存管理

    回收机制方式

    1、定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。

    2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

    3、实例如下:

    function fn1() {

        var obj = {name: 'hanzichi', age: 10};

    }

    function fn2() {

        var obj = {name:'hanzichi', age: 10};

       return obj;

    }var a = fn1();var b = fn2();

    fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

     4、垃圾回收策略:标记清除(较为常用)和引用计数。

    标记清除:

      定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。

      到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

    引用计数:

      定义和用法:引用计数是跟踪记录每个值被引用的次数。

      基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

    63:判断一个字符串中出现次数最多的字符,统计这个次数

    var str = 'asdfssaaasasasasaa';

    var json = {};

    for (var i = 0; i < str.length; i++) {

        if(!json[str.charAt(i)]){

           json[str.charAt(i)] = 1;

        }else{

           json[str.charAt(i)]++;

        }

    };var iMax = 0;var iIndex = '';for(var i in json){

        if(json[i]>iMax){

             iMax = json[i];

             iIndex = i;

        }

    }        console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次');

    64、$(document).ready()方法和window.onload有什么区别?

     (1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。

     (2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。

    65、 jquery中$.get()提交和$.post()提交有区别吗?

    相同点:都是异步请求的方式来获取服务端的数据;

    异同点:

    1、请求方式不同:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。

    2、参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。

    3、数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多

    4、安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。

    66、jQuery的事件委托方法bind 、live、delegate、on之间有什么区别?(常见)

    (1)、bind 【jQuery 1.3之前】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:bind(type,[data],function(eventObject));

    特点:

    (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

    (2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

    实例如下:$( "#members li a" ).bind( "click", function( e ) {} );

    (2)、live 【jQuery 1.3之后】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:live(type, [data], fn);

    特点:

    (1)、live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

    (2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

    (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 

    实例如下:$( document ).on( "click", "#members li a", function( e ) {} );

    (3)、delegate 【jQuery 1.4.2中引入】

    定义和用法:将监听事件绑定在就近的父级元素上

    语法:delegate(selector,type,[data],fn)

    特点:

    (1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

    (2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

    实例如下:

    $("#info_table").delegate("td","click",function(){/*显示更多信息*/});

    $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});

    (4)、on 【1.7版本整合了之前的三种方式的新事件绑定机制】

    定义和用法:将监听事件绑定到指定元素上。

    语法:on(type,[selector],[data],fn)

    实例如下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

     总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

    67、px和em的区别(常见)

     

    相同点:px和em都是长度单位;

    异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
    浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

    68、浏览器的内核分别是什么?

    IE: trident内核

    Firefox:gecko内核

    Safari:webkit内核

    Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核

    Chrome:Blink(基于webkit,Google与Opera Software共同开发)

    69、什么叫优雅降级和渐进增强?(常见)

    渐进增强 progressive enhancement:
    针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

    优雅降级 graceful degradation:
    一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

    区别:

    a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

    b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

    c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

    70、sessionStorage 、localStorage 和 cookie 之间的区别(常见)

     共同点:用于浏览器端存储的缓存数据

    不同点:

    (1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

            web storage,会将数据保存到本地,不会造成宽带浪费;

    (2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

    (3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

            sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

    (4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

     

    展开全文
  • 大部分人使用imdecode函数打开图像文件是因为 opencv中的imread函数无法打开中文估路径下的图像文件,网上使用imdecode函数打开图片的语法有很多这里简单列举一些: 方法一: def cv_imread(file_path = ""): file_...
  • WPF开发教程

    万次阅读 多人点赞 2019-07-02 23:13:20
    ------WPF 开发教程   目录 ...WPF基础入门.......目标就是提供在堆栈中处于较低位置的可扩展性点,这将允许外部开发人员可以在需要时创建自己的框架。 System.Windows.FrameworkElement ...
  • 网页设计\网页制作常用软件大全

    千次阅读 多人点赞 2014-03-04 12:08:26
    第一款彻底为Web制作者们设计的软件 Fireworks的来头实在不小,它的出现使Web作图发生了革命性的变化。Fireworks是专为网络图像设计而开发,内建丰富的支持网络出版功能,比如Fireworks能够自动切图、生成鼠标...
  • 一个谷歌浏览器扩展,彻底改变了维基百科网站的设计。 增强的设计包括更加用户友好的界面、排版增强以及整个网站的更现代感,并显着提高了可读性。 之前和之后 总体布局 图片 搜索 特征 更新:现已发布第 2 版在...
  • 软件测试入门知识了解

    万次阅读 多人点赞 2018-09-05 14:59:58
    明确自己的角色和责任 熟悉评审内容,为评审做好准备 针对问题阐述观点,而非针对个人 从客户角度想问题,多问几个为什么 在会前或会后提出自己建设性的意见 对发现的问题跟踪到底 针对需求文档等报告问题 7....
  • 机器学习和图像识别是怎样彻底改变搜索的? 简介 文本内容一般很好搜索,但有很多信息是以其他形式存在的。语音识别将音频-以及视频配乐-转换成可以索引和搜索的文本。但如果是视频本身,或其它的图片...
  • Flash

    千次阅读 2013-06-01 14:22:20
     基本概念:在一个关键帧上放置一个元件,然后 在另一个关键帧上改变该元件的大小、颜色、位置、透明度等,Flash根据两者之间帧的值自动所创建的动画,被称为动作补间动画。  2.Flash形状补间动画  ...
  • Android中图片压缩分析(上)

    千次阅读 2017-11-12 11:50:17
    此文章首发:...前者是在不改变图片尺寸的情况下,改变图片的存储体积,而后者则是降低图像尺寸,达到相同目的。由于本文的篇幅问题,分为上下两篇发布。二、Android 质量压缩逻辑在Andro
  • 《图书管理系统》毕业论文

    万次阅读 多人点赞 2008-11-24 11:13:00
    左上角的窗口提供了表单样式的预览功能,图片按钮和文本按钮的区别在于显示的时候是以图片来表达功能还是用文字来表示, 实现功能的函数没有区别。而不用的表单样式的区别在于选用不用风格的文本框和标签。选择...
  • css图片置灰

    千次阅读 2019-04-02 18:41:28
    背景图片置灰加上样式:background-blend-mode: hue; image图片置灰,给图片加样式 .gray { -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filter: ...
  • 投资与创业:程序猿如何改变世界

    千次阅读 2017-12-22 00:00:00
    本文来自作者 丹华CFA 在 GitChat 上分享 「投资与创业:程序猿如何改变世界」,「阅读原文」查看交流实录。「文末高能」编辑 | 哈比提示:建议阅读时播放 007 电影主题曲,效果更好。因为本文就是这么写出来的...
  • 这跟图片处理函数有关,默认生成JPG图片质量是75(也有说60,65),我们可通过改变函数参数提高图片显示效果 以ECShop2.7.2为例(其他版本类同),通常需要两步操作: 首先,最好让你的原始图片与后台设置的商品...
  • 以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。 ● eg2:(通过路径去图片) private ImageView preview; private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44....
  • 很多时候我们总想这文本与图片的转换,其实文本图片转换器的出现,就已经彻底改变我们的想法,因为他不但能够支持图片转换成各种格式,而且还操作起来相当的简单,让我们感觉像神一样的存在! 文本图片转换器...
  • 善待自己 改变命运的N个人生哲理

    万次阅读 2018-11-10 00:33:29
    善待自己 改变命运的N个人生哲理
  • 制作自己的CE彻底解决被封问题

    万次阅读 2015-04-27 23:35:17
    本帖由kwonboa原创 转贴请保留以上信息 谢谢 做有素质的中国人 由于过程非常长和复杂,建议非无...修改软件名称LOGO什么的标志图片把他变成你自己的UCE程序吧 第一步:所需要的软件 1.CE5.4原码:http://bbs.bps
  • 服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志...
  • 想读取本地项目里的资源图片,但又不能用到R文件。总结以下几种读取Bitmap的方法:1、以文件流的方式,假设sdcard里面有a.png图片FileInputStream fs = new FileInputStream("/sdcard/test.png");Bitmap ...
  • Android大图片处理

    千次阅读 2016-10-13 11:49:52
    移动设备对内存的要求还是很苛刻的,即便现在主流...图片来说更是OOM (OutOfMemoryError)的常见引发者,比如说系统图片库里展示的图片大都是用手机摄像头拍出来的,这些图片的分辨率会比我们手机屏幕的分辨率高得多。
  • 图片查看器-Python-tkinter

    千次阅读 2021-04-28 14:31:40
    图片浏览 2 图像缩放 3 图像旋转 4 切换浏览 5 拖拽查看 设计思路 设计思路概要 图像处理 PILLOW库实现 UI界面
  • 怎样把文件放在图片

    千次阅读 2014-05-31 22:58:37
    大小没有发生改变,这一点确实让人不可思议,但测试结果事实确实如此,我把刚刚用的test.txt,test.rar文件都彻底删除了,用WinRar打开test.jpg,结果还是一样的。刚刚只是一个很小的文本文件,换一个大点的文件试试...
  • dede修改文章页面的图片的完整路径

    千次阅读 2018-04-15 13:48:31
    终极 解决方法找到 include\dialog\select_images_post.php 第108行$fileurl = $activepath.’... 这样就可以完美实现dedecms上传图片相对路径改成绝对路了。dedecms升级到5.7SP1后,开启二级域名,你会发现,在...
  • 前端开发人员在引入is-promise包之后,就能在自己的项目中引用它,而且is-promise包是基于MIT协议的,因此引用该项目,也不必须要求开源。虽然只有两行代码,但is-promise 库却是当今最受欢迎的 JavaScript 软件包之...
  • 但是在动态改变的过程中,时不时出现图片无法显示 然后右键点击下 发现图片文件大小可获取 显示协议不可用等现象 当刷新下页面时 再进入时 这张图就可以显示了 在ie6,ie7.ff下 都是这个情况。 在网上查了很多人说...
  • 在项目中使用了Glide加载图片,今天遇到了图片的背景会变成绿色。网上找到了 解决方案。感谢Yaphet赵勇博主的分享: http://blog.csdn.net/yaphetzhao/article/details/50586991图片变色的原因是因为图片压缩所致...
  • JS实现Echarts的图表保存为图片功能

    千次阅读 2019-06-09 22:55:25
    实际项目开发过程中经常会有图表展示功能,同时为了满足用户需要,会附带着图表导出功能,主要形式就是保存为图片。在Echarts中本身就提供这种配置项,使用起来简单方便。但是,需求分析师要求必须有一个图表导出...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,778
精华内容 12,711
关键字:

彻底改变自己的图片