Python自动化运维课程学习--Day2

本文为参加老男孩Python自动化运维课程第二天学习内容的总结。

大致内容如下:

  1、python模块初识

  2、python程序运行流程

  3、python数据类型(只讲了numbers, bool, strings, bytes, list, tuple, dict, set)

  4、python数据运算

0、关于本文中所有运行Python代码的环境:

   --操作系统:Ubuntu 16.10 (Linux 4.8.0)

      

   --Python版本:3.5.2

      

   --Python IDE: PyCharm 2016.3.2

      

1、Python模块初识,Python模块分为标准库和第三方库:  

      1) 标准库(build-in lib)为安装python后自带的模块(库),一般存放在安装路径下的lib文件夹下:

      Windows:C:\Users\[username]\AppData\Local\Programs\Python\Python35\Lib\

      Linux: /usr/lib/python3.5/

    2) 第三方库:在安装好python后,需要另外安装的模块(库),一般存放在安装路径下的site_packages文件夹下:

      Windows:C:\Users\[username]\AppData\Local\Programs\Python\Python35\Lib\site_packages\

      Linux: /usr/lib/python3.5/site_packages/

要引用这些模块中的功能,必须在python代码的开头通过 import 导入要引用的模块后,才能使用模块中的各个功能。

本节课就只简单的来了解下sys和os两个标准模块。

1)sys模块:提供python解释器与用户交互的接口功能。如sys.exit(),sys.path等。

    官方解释:This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter. It is always available.   详见https://docs.python.org/3.5/library/sys.html#module-sys

            sys.path: 打印Python全局环境变量

     sys.arve: 如果在执行python程序时,后面没有跟任何参数(参数间以空格隔开),打印python代码文件的路径;

          如果有参数,则打印所有参数(以lists的形式打印);

          如果是sys.arve[N]:则打印后面的第N个参数。如果N大于后面参数的总个数,则报“out of range”错。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: check the sys mode with sys.path and sys.argv
# Author: Spencer Jiang
# Date: 2017-02-18

import sys

# 打印Python的全局环境变量信息
print("sys.path", sys.path)

# 打印Python程序文件路径(Windows下是绝对路径,Linux下是相对路径)
print("\nsys.argv", sys.argv)

# 打印执行Python程序文件跟着的第1个参数
print("\nsys.argv[1]", sys.argv[1])

# argv报错:out of range
print("\nsys.argv[1]", sys.argv[10])

# End Of File

    

2)os模块:提供python解释器与操作系统交互的接口功能。如os.path,os.error等。

    官方解释:This module provides a portable way of using operating system dependent functionality. 详见https://docs.python.org/3.5/library/os.html#module-os

            os.system("") : 调用系统命令,如os.system("ls -lh")、os.system("dir")等。

os.mkdir(""): 调用系统的mkdir命令创建目录

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: check the os mode with os.open(), os.system(), os.popen(), os.mkdir()
# Author: Spencer Jiang
# Date: 2017-02-18

import os

# 调用系统命令ls -lh 显示当前路径下所有文件和目录列表
print(os.system("ls -lh"))

cmd_line = os.system("ls -lh")

# 如果命令执行成功,则返回1,否则为0
print("\ncmd_line: ", cmd_line)

# 创建test_day2文件夹
os.mkdir("test_day2")

# 用popen()替换system()
cmd_result = os.popen("ls -lh")

# 打印在内存的地址
print("\ncmd_result Address in memory: ", cmd_result)

# read() 打印cmd_result的值
print("\n cmd_result : ", cmd_result.read())

# 再创建test_day2文件夹,报错
os.mkdir("test_day2")

# End Of File

    

 

 2、Python程序运行流程  

     Python是解释型语言,在执行过程中涉及到两个概念:PyCodeObject 和 pyc文件

      PyCodeObject: 指Python代码执行时的结果保存在内存中的对象

pyc文件: 指Python代码执行结果保存到磁盘上的文件,可视为PyCodeObject的持久化存储。所以我们会在执行python代码后,在python代码文件(.py)同路径下看到一个与python代码文件同名的.pyc文件。

    

3、Python数据类型(numbers, bool, strings, bytes、list、tuple、dictionary、set)

    Numbers:有int、long、fload、complex(复数)

    Bool:True(数字1)、False(数据0): 在Python2中是没有布尔型的,它用数字0表示False,用1表示True。在Python3中,把True和False定义成关键字了,但它们的值还是1和0,它们可以和数字做运算。

    Strings:字符串,单引号或双引号或三引号。字符串拼接:修改字符串内容时,就需要再次开辟内存空间,通过“+”拼接字符串也是一样的道理。

    Bytes:Bytes 对象是由单个字节作为基本元素(8位,取值范围 0-255)组成的序列,为不可变对象。Bytes 对象只负责以二进制字节序列的形式记录所需记录的对象,至于该对象到底表示什么(比如到底是什么字符)则由相应的编码格式解码所决定。(参考https://segmentfault.com/a/1190000004450876)

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: check the bytes
# Author: Spencer Jiang
# Date: 2017-02-18

str_name = "字符串"

print("name--utf-8: ", bytes(str_name, "utf-8"))

print("name--gb2312: ", bytes(str_name, "gb2312"))

    

   

     list(列表):

        1)有序的元素集合,以方括号为开始和结束标记,各元素以逗号隔开,如 list_a = [1, 2, 3, 4, "test"]。

2)列表的起始下标是0。

      3)列表支持的操作:

        A、查询:取某下标的元素值list_a[i]、取某元素对应的下标list_a.index("test")、对某元素计数list_a.count(1)。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: list query ops
# Author: Spencer Jiang
# Date: 2017-02-27

list_a = [1, 2, 3, 4, "test", 4, "abc"]
print(list_a)

# 取某下标的元素值
print(list_a[4])
print(list_a[-1])

# 取某元素对应的下标
print(list_a.index("test"))

# 对某元素计数
print(list_a.count(4))

      

B、切片:取某个范围内的所有元素 list_a[i:j:len],i为起始下标,缺省时为0;j为结束下标,缺省时为list_a的长度-1;len为步长,缺省时为1。

    

        C、更新

          在列表末尾添加新的元素:list.append(value);

在列表指定位置插入一个元素:list.insert(i, value);

在修改指定下标对应元素的值:list[i]=value;

将列表中所有元素的数据类型都一致的按ASCII码排序:list.sort(); 如果列表中元素既有数字,又有字符串,则sort()函数会报错“TypeError: unorderable types: str() < int()”。

将列表中所有元素反转过来:list.reverse();

不同列表的拼接:list_a.extend(list_b),将列表list_b中所有元素连接到list_a的末尾。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: list query ops
# Author: Spencer Jiang
# Date: 2017-02-27

list_a = [1, 2, 3, "test", 4, "abc"]
print("list_a:", list_a)

# 在列表末尾添加新的元素
list_a.append("hello")
print("list_a.append(‘hello‘):", list_a)
# 在列表指定位置插入一个元素
list_a.insert(2, 123123)
print("list_a.insert(2, 123123):", list_a)
# 修改指定下标对应元素的值
list_a[1] = "b"
print("list_a[1]:", list_a)
# 将所有元素按ASCII码排序
# list_a.sort()  # 列表中元素既有数字又有字符串,则sort()函数会报错“TypeError: unorderable types: str() < int()”

list_b = [123, 3, 54, 234, 23, 4]
list_b.sort()
print("list_b.sort():", list_b)
# 将列表中所有元素反转
list_b.reverse()
print("list_b.reverse():", list_b)

# 将列表list_a中所有元素连接到list_b的末尾
list_b.extend(list_a)
print("list_b.extend(list_a):", list_b)

      

        D、删除

            删除列表中最后一个元素:list_a.pop()

            删除列表中指定的元素:list_a.remove(value)

删除列表中指定下标的元素:list_a.pop(i)

            删除列表中指定下标的元素:del list_a[i]

            清空列表中所有的元素: list_a.clear()

            删除整个列表: del list_a

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: list query ops
# Author: Spencer Jiang
# Date: 2017-02-27

list_a = [1, 2, 3, "test", 4, "abc", "cde"]
print("list_a:", list_a)

# 删除列表中最后一个元素:list_a.pop()
list_a.pop()
print("list_a.pop():", list_a)

# 删除列表中指定的元素:list_a.remove(value)
list_a.remove("abc")
print("list_a.remove(‘abc‘‘):", list_a)

# 删除列表中指定下标的元素:list_a.pop(i)
list_a.pop(1)
print("list_a.pop(1):", list_a)

# 删除列表中指定下标的元素:del list_a[i]
del list_a[1]
print("del list_a[1]:", list_a)

# 清空列表中所有的元素: list_a.clear()
list_a.clear()
print("list_a.clear():", list_a)

# 删除整个列表: del list_a
del list_a
print(list_a)      # list_a对象被删除,打印报错"name ‘list_a‘ is not defined"

      

        E、拷贝操作:copy

            直接将一个列表赋值给另一个列表:list_b = list_a,list_b与list_a中所有元素都会实时保持一致。

            浅copy: list_a = list_b.copy() 或 通过 导入copy包,list_a = copy.copy(list_b),只有对嵌套列表中的元素才会实时保持一致。

深copy:通过导入copy包, list_a = copy.deepcopy(list_b),不管是不是嵌套列表,所有元素都会实时保持一致。

           tuple(元组):元组是不可变的列表,以括号为开始和结束标记,各元素以逗号隔开,如 tuple_a = (1, 2, 3, "test"),起始下标为0。

元组支持的操作:取某下标的元素值tuple_a[i]、取某元素对应的下标tuple_a.index("test")、对某元素计数tuple_a.count(1)。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: check tuple
# Author: Spencer Jiang
# Date: 2017-02-27

# 元组是不可变的列表,以括号为开始和结束标记,各元素以逗号隔开
name_tuple = (1, 2, 3, "wu", "test", "SZ", "wu")
print(name_tuple)
# 起始下标为0
print(name_tuple[1])
# 对某元素计数
print(name_tuple.count("wu"))
# 取某元素对应的下标
print(name_tuple.index("SZ"))

    

   

     set(集合):无序的,能自动去重的数据组合,通过set()函数定义, set_a = set("hello, python")。

set_a = set("hello, python")

print(set_a)
{‘y‘, ‘ ‘, ‘h‘, ‘e‘, ‘,‘, ‘l‘, ‘t‘, ‘n‘, ‘p‘, ‘o‘}     # 打印结果

       A、运算操作

           取set_a 和 set_b 的并集: set_a | set_b

取set_a 和 set_b 的交集: set_a & set_b

           取set_a 和 set_b 的差集: set_a - set_b

           取set_a 和 set_b 的对称差集: set_a ^ set_b

set_a = set("hello, python")
print(set_a)
set_b = set("hello, world")
print(set_b)
# 取set_a 和 set_b 的并集: set_a | set_b
print(set_a | set_b)
# 取set_a 和 set_b 的交集: set_a & set_b
print(set_a & set_b)
# 取set_a 和 set_b 的差集: set_a - set_b
print(set_a - set_b)
print(set_b - set_a)
# 取set_a 和 set_b 的对称差集: set_a ^ set_b
print(set_a ^ set_b)

     

          B、新增操作

            新增1个元素:set_a.add(value)

            新增多个元素:set_a.update(value1, value2, value3...) 

            合并两个集合:set_a.union(set_b),等于set_a | set_b

          C、删除

            随机移除一个元素: set_a.pop()

            移除某个元素: set_a.remove(value)

set_a = set("hello, python")
print(set_a)

set_a.add("1")
set_a.update("2", "3")
print(set_a)

set_a.remove("h")
print(set_a)

print(set_a.union(set("HELLO")))

set_a.pop()
print(set_a)

## 运行结果
{‘o‘, ‘e‘, ‘l‘, ‘t‘, ‘n‘, ‘,‘, ‘p‘, ‘y‘, ‘h‘, ‘ ‘}
{‘o‘, ‘e‘, ‘l‘, ‘t‘, ‘2‘, ‘n‘, ‘,‘, ‘p‘, ‘y‘, ‘h‘, ‘3‘, ‘ ‘, ‘1‘}
{‘o‘, ‘e‘, ‘l‘, ‘t‘, ‘2‘, ‘n‘, ‘,‘, ‘p‘, ‘y‘, ‘3‘, ‘ ‘, ‘1‘}
{‘o‘, ‘L‘, ‘E‘, ‘H‘, ‘e‘, ‘l‘, ‘t‘, ‘2‘, ‘n‘, ‘O‘, ‘,‘, ‘p‘, ‘y‘, ‘ ‘, ‘3‘, ‘1‘}
{‘e‘, ‘l‘, ‘t‘, ‘2‘, ‘n‘, ‘,‘, ‘p‘, ‘y‘, ‘3‘, ‘ ‘, ‘1‘}

         D、比较操作:

          获取set_a中所有不属于set_b的元素: set_a.difference(set_b)          

    dictonary(字典):无序的key-value对数据集合,key必须是唯一的。以大括号{}开头和结束,key和value前以冒号分隔。

        A、查询:查询某key对应的值:dist.get(key)、dist[key]

            获取所有的key: dist.keys()

            获取所有的value: dist.values()

            获取所有key-value: dist.items()

        B、更新

            更新某个key的值:dist[key] = value,如果key不在,则新增;存在则更新

            设置某个key的默认值:dist.set(key, value)            

            合并两个dist:disct.update(dist_b),将dist_b合并到dist中,如果key重复,则覆盖

         C、删除:删除某个指定key-value:dist.pop(key)

            随机删除某个元素:dist.popitem()

            删除某个指定key-value:del dist(key)

    

dis_person = {
    "Spencer": {
        "sex": "boy",
        "age": 23,
        "job": ["Dev", "Test"]
    },
    "Jack": {
        "sex": "boy",
        "age": 17,
        "job": "stud"
    },
    "Jen": {
        "sex": "girl",
        "age": 22,
        "job": "stud"
    }
}

print(dis_person["Spencer"])
print(dis_person["Spencer"]["job"])
print(type(dis_person.keys()), dis_person.keys())
print(dis_person.get("Jen"))
print(type(dis_person.items()), dis_person.items())
print(dis_person.values())

dis_person["Spencer"].pop("job")
print(dis_person["Spencer"])

   附上整理的数据类型思维导图:

4、Python数据运算 及 运算优先级         

        1、算数运算:  +(加)、 -(减)、 *(乘)、 /(除)、  %(取模)、 //(取商的整数部分)、 **(幂)

在计算机中,所有的算数运行,都要先转换成二进制后再进行运算。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: practice of the calculator
# Author: Spencer Jiang
# Date: 2017-02-22

a = 123
b = -321

print("123 + (-321)=", a + b)

print("123 - (-321)=", a - b)

print("123 * (-321)=", a * b)

print("(-321) / 123=", b / a)

print("123 % (-321)=", a % b)

print("(-321) // 123=", b // a)

print("123 ** 2=", a**2)

    

2、比较运算符: ==(判断两个对象是否相等)、 !=(判断两个对象是否不相等)、 >(大于)、 <(小于)、 <>(不相等,不建议用这个符号)、 >=(大于等于)、 <=(小于等于)

3、赋值运算符[在算数运算符后面加个等号(=)]:=(简单的赋值)、 +=(加法赋值)、 -=(减法赋值)、 *= (乘法赋值)、/=(除法赋值)、%=(取模赋值)、//=(取商的整数赋值)、**=(取幂赋值)

  4、逻辑运算符:or(或)、and(与)、not(非),用于条件判断语句中对单个或多个条件的运算。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: user login input
# Author: Spencer Jiang
# Date: 2017-02-25

user_name = input("please input username: ")
password = input("Please input password: ")

_username = "spencer"
_password = "1234abcd"

if user_name == _username and password == _password:
    print("Welcome, login successfully!!")
elif user_name != _username or password != _password:
    print("Invalid username or password!!")
else:
    print("I am not happy!")

    

  5、成员运算:in(如果在指定的列表中能找到则返回True,否则为False)、not in(如果在指定的列表中没有能找到则返回True,否则为False)

6、身份运算:is(判断两个标识是否引用同一个对象)、 not is(判断两个标识是否不是引用同一个对象)

7、位运算:&(按位与)、 |(按位或)、^(按位异或)、~(按位取反)、<<(左移运算)、>>(右移运算)

    1)按位与运算(&):两个数的二进制各位上的数值都为1(真)时,才为1(真);否则就是0(假)。

      示例:a, b = 123, -123

a & b = 0111 1011 & 1000 0101 = 0000 0001 = 1

      注:负数在二进制里是以补码来表示的——以b=-123为例:

        a)先取其绝对值的二进制值(按8位二进制来算,123的二进制是 0111 1011、首位加0表示正数、首位加1表示负数)

        b)再进行按位取反,变为:1000 0100

c)末位加1,就是补码:1000 0101

    2)按位或运算(|):两个数的二进制各位上的数值只要有一个为1(真)时,就为1(真);否则就是0(假)。

       a | b = 0111 1011 | 1000 0101 = 1111 1111 = -1

     3)按位异或运算(^):两个数的二进制各位上的数值同时都为1(真)、或者同时为0(假)时,就为0(假);否则就是1(真)。

       a ^ b = 0111 1011 ^ 1000 0101 = 1111 1110 = -2

    4)按位取反(~):只对1个数进行操作,对二进制数各位上数值取相反的一位,即若为0,则取反就变1;若为1,则取反为0。  

      (1) 正数的取反 过程:  ~a = -124 = -(a+1)
           a、将正数转换成 二进制数(按8位二进制来算),并在最前面加一个符号为 0 表示正数,1 表示负数:
             如 a = 123; 二进制数为: 0 0111 1011
           b、 取该二进制数的补码: 0 0111 1011 (正数的补码为其本身,负数的补码为按位取反末位加1)
           c、在按位取反: 1 1000 0100 
           d、再按位取反(符号位不变): 1 0111 1011  
           e、如果首位是1(表示负数),末位需加1。 1 0111 1100  (-124)

      (2) 负数的取反 过程:  ~b = 122 = -(b+1)

        a、将正数转换成 二进制数,并在最前面加一个符号为 0 表示正数,1 表示负数:
          如 b= -123; 取其绝对值的二进制数,最前面加符号位,为: 1 0111 1011
        b、 取该二进制数的补码: 0 1000 0101 (正数的补码为其本身,负数的补码为按位取反末位加1)
        c、再按位取反(符号位不变): 0 0111 1010 (122)

    5)左移运算:只对1个数的操作,表达式为:A<<X,表示 A的二进制所有位向左移X位,右边补0。

    6)右移运算:只对1个数的操作,表达式为:A>>X,表示 A的二进制所有位向右移X位。

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: Bitwise operations
# Author: Spencer Jiang
# Date: 2017-02-25

a = 123
b = -123

print("binary of %d is  0011 1101" % a)
print("binary of %d is  1000 0101" % b)

print("b<<2 = ", b << 2)
print("a>>2 = ", a >> 2)

    

8、三元运算: 对3个操作数的运算

#!/usr/bin/python3.5
# -*- coding:utf-8 -*-
# Function: three opts
# Author: Spencer Jiang
# Date: 2017-02-25

b, c = 5, 19

a = c if b > c else c

print(a)

    

最后:Python是面向对象的编程语言,在Python里一切皆对象。

第二周作业------购物车

1、分为用户入口和商家入口
2、用户入口:
    1)、首次运行程序才需要输入存款(工资)
    2)、从文件中读取商品信息
    3)、购买商品后,显示己购商品列表、账户余额,并都保存到文件中
3、商家入口:
    1)、可以添加商品、修改商品价格
    2)、商品信息保存在文件中

时间: 2024-10-01 22:02:23

Python自动化运维课程学习--Day2的相关文章

Python自动化运维课程学习--Day3

本文为参加老男孩Python自动化运维课程第三天学习内容的总结. 大致内容如下: 1.文件操作 2.字符编码转码相关操作 3.函数 0.关于本文中所有运行Python代码的环境: --操作系统:Ubuntu 16.10 (Linux 4.8.0) --Python版本:3.5.2 python2.7.12 --Python IDE: PyCharm 2016.3.2 一.文件操作: 1.文件操作流程:以只读.写(覆盖写).追加写.读写.追加读写.二进制读写等模式打开文件 ==> 得到文件句柄,并

python自动化运维培训学习记录-day2

day02  基础二 一. .pyc 文件简介 3版本中   .pyc 会 移到    __pycache__ 目录下,名称 为  *.cpython-32.pyc java是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成及其文件,所以JAVA是一种先编译后解释的语言 python和Java/c# 一样,也是一门基于虚拟机的语言, 而python执行时先自动编译,执行py 脚本时,其实是激活了python的解释器,告诉解释器,你要开始工作了,可在解释之前,其实执行的第一项工作和jav

【Python自动化运维之路Day2】

1. 常量命名规则 在Python中,会在变量命名上标明某变量是常量,通常采用全是大写的方式来标明,如: CONNECT= '127.0.0.1' PORT = '3306' 2.Python编译 python先把源码文件(.py)编译成字节码文件(.pyc) python3执行后,生成了一个__pycache__目录,pyc会在此目录下,python2执行可以看到直接生成了一个.pyc文件 pyc  与py  时间戳不同,pyc才去重新编译 3  数据 <1> str 1.str1+str2

python自动化运维培训学习记录-day1

day01  基础一 一.概述 C  语言   代码编译得到机器码,在处理器上直接执行,每条指令控制CPU工作 其他语言  代码编译得到字节码,虚拟机执行字节码并转换成及其码再到处理器上执行 JAVA虚拟机 JVM     python虚拟机 PVM python版本 CPython   由C语言实现,官方版本 JPython    由JAVA实现, 好处是 可以掉很多JAVA的库 IronPython  由C#实现 .... 2.7版本 过度版本,只支持到 2020年,会直接换到起码 3.4版

电子书 Python自动化运维:技术与最佳实践.pdf

本书在中国运维领域将有"划时代"的重要意义:一方面,这是国内一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的作者是中国运维领域的"偶像级"人物,本书是他在天涯社区和腾讯近10年工作经验的结晶.因为作者实战经验丰富,所以能高屋建瓴.直指痛处,围绕Python自动化运维这个主题,不仅详细介绍了系统基础信息.服务监控.数据报表.系统安全等基础模块,而且深入讲解了自动化操作.系统管理.配置管理.集群管理及大数据应用等高级功能.重要的是,完整重现了4个

Python自动化运维开发活动沙龙(2015-07-11周六)

Python自动化运维开发活动沙龙 2015-07-11(周六) 场地限制,最多仅限50人参加,报名从速! 亲,已是2015年了,做为运维工程师的你还在手动装机器.配服务.看监控.帮开发人肉上线么?还在发愁如何把每天重复的工作自动化起来么?还在想对开源软件进行二次开发定制却无能为力么?还在对开发人员提出的各种无理需求想进行反驳却因为自己不懂开发却被人鄙视么?还在为自己天天努力工作.到处救火却每月只能挣个十来K而感到不爽么? Maybe yes,maybe no! 但是不要不爽了,你的工资不高是因

Python自动化运维Django入门

随着IT运维技术日益更新,近几年运维自动化越来越火,而且学习python的人非常的火爆,尤其是python自动化运维开发,得到了很多前辈的推崇,尤其是老男孩培训中心.老男孩老师.Alex老师等,在这里非常感谢你们. 这里我也记录一下以前学习Django的一点点心得和方法,方便以后自己查阅,如果能帮助初学者是最好的了!好的,其他不多说了,博文滴走起. 一.系统实战环境 系统版本:CnetOS6.5 x86_64 Django版本:Django-1.5.8 MySQL版本:MySQL-5.1.73

python自动化运维之路~DAY7

python自动化运维之路~DAY7 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.客户端/服务器架构 C/S 架构是一种典型的两层架构,其全称是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据:另一种是Socket服务器端,服务器端的程序通过Socket与客户端的程序通信. C/S 架构也可以看做是胖客户端架构.因为客户端需要实现绝大多数的业务

python自动化运维之路~DAY10

python自动化运维之路~DAY10 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.