Python基础学习

目录

一、概述

1.编译型和解释型语言

2.Python的设计目标

3.Python特点

二、第一个Python程序

1.Python源程序格式

2.执行Python的方式

三、Python基础语法

1.算术运算符

2.变量

3.分支语句

4.while循环

5. 函数

5.1 基本使用

5.2 内置函数

 5.3 Lambda表达式

 5.4 装饰器

6.模块

7.高级变量类型

 7.1 序列结构

7.2 推导式

7.3 序列切片

4.完整for循环

四、Python面向对象

1.可变类型和不可变类型

2.创建类

初始化方法

身份运算符

私有属性和私有方法

3. 继承

4.单例

单例实现:

5.异常

6.文件

五、其他补充

5.1 With语句

5.1.1 with和上下文管理器

 5.1.2 contextlib 

总结


一、概述

1.编译型和解释型语言

        编译型:程序之前前需要一个专门的编译过程,把程序编译成机器语言文件,运行时不需要重新编译。程序运行效率高,跨平台性差

        解释型:程序不进行预先的编译,程序执行时逐行解释;运行效率较低但具有跨平台性

2.Python的设计目标

        简单直观的语言;开源,供任何人共同开发;易于理解;使用短期开发项目

3.Python特点

        完全面向对象;拥有一个强大的标准库;提供大量的第三方模块

二、第一个Python程序

1.Python源程序格式

        Python源程序是一个特殊格式的文本文件,可以使用任意文本编辑器;文件可扩展名.py

        与大多数UNIX系统和服务不同,Windows系统没有预安装Python。为了方便直接使用Linux操作系统

print("hello python")
print("hello hello world")

        终端输入:python 文件路径

        Python中代码必须整齐,不要有缩进;否则报错;初期不要加缩进

        python2.x 版本不支持中文;pythonn3.x默认支持;下面使用python3运行程序

        Python中的注释采用 # 进行单行注释;为了保证代码的整体,官方建议# 后面添加一个空格;如果和代码写在一行,建议代码和注释之间有两个空格

        多行注释使用连续的引号,单引号或双引号都可以

 我改用IDEA了(heihei)

2.执行Python的方式

        1.解释器类型

 # 2.x 版本   语法: python 文件名

# 3.x 版本    语法: python3 文件名

        2.交互型

        命令行终端 输入:python后,输入python代码

        缺点:适合小功能的语法学习,不方便大量程序编写;退出后(exit() / ctrl + D)代码不能保存

        3.集成开发软件(PyCharm)

三、Python基础语法

1.算术运算符

        Python中 + 可以用于相同数据类型对象的相加,但不支持字典和集合

        这里不同的就是 幂,采用两个**

        

* 运算符还可以用于字符串,用于重复 给定字符串相应的次数

print("test" * 10)

输出:testtesttesttesttesttesttesttesttesttest

2.变量

        Python的变量只用第一次出现才算定义变量;Python中不需要指定数据的类型,程序运行时由解释器自动推断准确类型

        数据类型分为:数字型和非数字型

        数字型:int, float, bool, complex(复数型,主要用于科学计算,如波动问题,微积分)

        非数字型:字符串,列表,元祖,字典

Python3中,int 和 long 被整合到一起,只有一个 int 类型,不需要进行区分

Python中,bool类型的true表示1, false表示0

数字型变量之间是可以直接进行计算的

 2.2 转义字符:当在字符串中包含\n等会被认为是转义字符,在字符串前面添加r或R表示不转义。

        如:r'C:\windows\notepad.exe'

           变量的输入:使用函数input() 

  格式:字符串变量 = input("字符串提示信息")

        类型转换函数:int(x), float(x)

输入格式化与其他语言类似, 如:

print("苹果价格 %f, 重量 %d, 共花费 %f" % (apple_price, apple_weight, money))

3.分支语句

        if 语句,书写格式:

if 条件判断:

        成立执行的代码

  Python中缩进使用Tab或者四个空格,建议使用空格

  Python中不需要使用{}, 对于if中的多条语句使用缩进进行判断;

  Python中的elif 中间没有空格,用于多分支判断

value = 17
if value >= 18:
    print("if内部")
    print("if第二句") # if语句结束部分
print("if外部")

Python中的逻辑连接词是 and, or, not

Python中没有自增运算

4.while循环

        让指定代码重复执行

Python中的print自带换行,如果不希望添加,可以在print内部加入end=“”

Python总的for循环,使用for ... in 进行迭代遍历

5. 函数

5.1 基本使用

        Python中定义函数语法:def 函数名():

def sum(num1, num2):
    """对两个数进行求和"""
    return num1 + num2


res = sum(2, 3)
print(res)

不用像其他语言指定返回值的类型

Python中函数的参数以及返回值都是引用类型;可以通过id()查看变量保存的地址;这里的传参应该参考java,和c语言不同

def swap(num1, num2):
    print(id(num1))  # 140725073575008
    temp = num1
    num1 = num2
    num2 = temp
    print(id(num1))  # 140725073575040
    return (num1, num2)  # 当返回类型是元组的时候,小括号可以省略

num1 = 2
num2 = 3
print("%d - %d" % (num1, num2))  # 2 - 3
print(id(num1))  # 140725073575008
(num1, num2) = swap(num1, num2)
print(id(num1))  # 140725073575040

print("%d - %d" % (num1, num2))  # 3 - 2

定义在函数外部的变量称为全局变量,函数内部不允许对全局变量进行修改;

如果在函数内部想要修改全局变量,只会在函数内部创建一个同名的局部变量

想要修改全局变量,需要在赋值语句前面使用global关键字声明变量

缺省参数:

        缺省参数必须在函数参数列表的末尾

        当含有多个缺省参数的时候,需要添加参数名

def print_info(name, gender_text="男生"):
    """

    :param name: 姓名
    :param gender_text: 性别,默认男生
    :return:
    """
    print(name, gender_text)


print_info("小红")  # 小红 男生
print_info("小红", "女生")  # 小红 女生

多值参数:当出入的参数个数不确定

        变量前面添加 * 表示元组;添加 ** 表示字典;

        一般使用 *args 作为列表命名, ** kwargs表示字典

def demo(*args, **kwargs):
    
    print(args)
    print(kwargs)


gl_nums = {1, 2, 3}
gl_dict = {"name": "小明", "age": 18}

# 拆包语法,在想要传递的相应的参数前面添加* 或 **
# 拆包可以简化元组和字典变量的传递
demo(*gl_nums, **gl_dict)

5.2 内置函数

range(start, end)遍历区间,默认步长step = 1
range(end)step = 1, start = 0
min(), max(), sum()取最小,最大, 总和
eval()计算字符串表达式,如 eval('1 + 2')
print()

print(value, sep = "", end = '');

sep表示间隔符,end为结尾,默认是换行

sorted(iterable, key, reverse)

排序; iterable为迭代对象,key为排序规则

reverse是否降序

enumerate()返回可迭代的enumerate对象,需使用list()查看
map(function, iterable)将function函数依次映射到序列或迭代器对象
filter(function, iterable)将function函数(必须是单个参数)依次映射到序列或迭代器对象
open(file, mode = 'r', encoding = 'utf-8')打开磁盘文件

 5.3 Lambda表达式

  匿名函数,减少代码量;使用该语法糖返回的是一个匿名函数,可以在需要小函数的地方定义lambda

        语法:lambda argument_list: expression    # argument_list为参数,expression为表达式

f = lambda x, y : x + y
f = ('我学', 'Python')  # 变量赋值,间接调用lambda, 结果:我学Python

# 作为参数
x = filter(lambda x : x % 3 == 0, [1, 2, 3, 4, 5, 6])
# [3, 6]

 5.4 装饰器

  •  基本使用

代码运行期间动态增加功能的方式,称之为“装饰器”,理解成非业务功能切面添加到代码中

目前包含一个函数:

def add(x, y):
    return x + y

 装饰器的含义我理解的就是:将目标函数作为参数传递给一个自定义的装饰函数(decorator), 这个函数可以接收任意的参数

装饰函数:

日志函数
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

在目标函数上面添加:@log,为函数进行增强

@log()  # 相当与调用log(add)
def add(x, y):
    return x + y

此时正常调用add函数的时候,会自动调用log函数,即:log(add)

  • 带有参数的装饰器
@log("test")  # 相当与调用log("test")(add)
def add(x, y):
    return x + y

 定义装饰函数:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('call %s-%s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

 调用链路:log("test") -> 返回decorator(func) -> wrapper

当使用__name__获取信息的时候,最终拿到的是wrapper类型;

由于某些情况我们需要原始的__name__信息,因此可以使用  @functools.wraps(func)  # 将装饰函数名字修改为原函数

修改后的装饰函数:

import functools
def log(text):
    def decorator(func):
        @functools.wraps(func)  # 将装饰函数名字修改为原函数
        def wrapper(*args, **kw):
            print('call %s-%s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

6.模块

        模块就好比是工具包,Python中以.py结尾的源代码文件都可以是一个模块,通过import进行导入;模块中的全局变量,函数可供外界访问

        模块名也是一种标识符,所以只能由字母,下划线和数字组成,数字作为开头

        导入的模块首先由Python解释器进行一次编译

        局部导入:from 模块名 import 工具名

导入的时候,导入文件中没有缩进的代码会被自动执行

为了避免导入的文件中不执行没有缩进的测试代码,可以使用__name__判断,如果是当前文件执行,__name__默认是__main__;否则,就是模块名

if __name__ == __main__:
    # 执行测试代码,可以将测试代码写到一个main()函数中
    main()

7.高级变量类型

 7.1 序列结构

        指一块可存放多个值的连续内存空间,按一定顺序排列,可通过索引进行访问;其中字典和集合是无序的,不能索引访问。元组,字符串是不可变序列

        静态变量为传值拷贝,动态变量(列表,字典,集合)为引用拷贝

        1.列表

        - 基础语法

        其他语言中的数组,使用 [] 定义;可以存储不同类型的变量del 关键字将变量从内存中删除,后续的代码不能继续使用这个变量

列表的比较需要引入 operator  中的eq 方法

          2.元组(Tuple)

        - 基础语法

        与列表相似,不同的在于元组中的元素值不能被修改, 使用()定义

TypeError: 'tuple' object does not support item assignment

# 测试元组
tuple_array = ()  # 定义一个空元组
print(tuple_array)
print(type(tuple_array))

tuple_array1 = (1, "asdfasdf", True)
print(tuple_array1)
print(type(tuple_array1))

tuple_array2 = (5)  # 只有一个元素的元组
print(tuple_array2)
print(type(tuple_array2))  # <class 'int'>

tuple_array3 = (5, )  # 定义只有一个元素的元组的时候,需要用逗号分隔
print(tuple_array3)
print(type(tuple_array3))  # <class 'tuple'>

可以使用list()tuple()进行列表和元组之间的相互转换 

元组是不可修改的,但是可以进行拼接:

tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
 
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
 
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)

3.字典

        - 基础语法:

        类似map集合,使用键值对存储,内部无序;键 只能使用数字,字符串或者元组;键值对之间使用:分隔; 键必须唯一; 类型:<class: dict>

        使用{} 定义,一般存储物体的信息

  • 可以通过key访问字典中的元素:
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
 
print ("tinydict['Name']: ", tinydict['Name'])
  • 删除字典中的元素

tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
 
del tinydict['Name'] # 删除键 'Name'

字典的key是不可变的,因此不能使用列表充当,可以使用数字或者元组

7.2 推导式

  • 4.1 列表推导式  [val for val in list_item if condition]
a = [x * x for x in range(6)]

# 等价于
a = []
for x in range(6):
    a.append(x * x)
  • 4.2 字典推导式  {key:value for key_, val_ in dict.items() if condition}
  • 4.3 集合推导式  {key for key_ in dict.items() if condition}
  • 4.4 元组推导式  (val for val in list_item if confition)

    - Python生成器(元组推导式):与列表推导式类似,但是生成器返回的是迭代器对象,具有惰性机制,里面的元素只有在访问的时候才会生成,一旦访问立即释放内存。

        语法:(表达式 for 变量 in 序列或迭代对象) 或

                   (表达式 for 变量 in 序列或迭代对象 if 条件表达式)

# 列表生成器
L = [(i + 1) ** 2 for i in range(6)] 
# L = [1, 4, 9, 16, 25, 36], 运行结束就占用内存

# 生成器
G = ((i + 1) ** 2 for i in range(6))
# G , 只有在访问的时候才会占用内存

7.3 序列切片

        切片是序列元素的另一种方法,可以访问一定范围内的元素,生成新的序列

        语法:序列名称[开始 : 结束 : 步长]

公共方法

# 使用加号拼接列表,会生成一个新的列表
print([1, 2] + [3, 4])

list1 = [1, 2]
list2 = [3, 4]
list1.extend(list2)  # 将列表追加到原来的列表中,不生成新列表
print(list1)  # [1, 2, 3, 4]

list1.append(list2)  # 将 list2整体看做一个元素添加
print(list1)  # [1, 2, 3, 4, [3, 4]]

4.完整for循环

        for ... in :

                for循环中执行的代码

        else 

                for循环中没有经过break退出,完成执行完for循环后会执行这段代码


四、Python面向对象

1.可变类型和不可变类型

        可变类型:数字型,字符串和元组

        不可变类型:列表,字典; 通过相应的方法可以操作列表或字典中的数值;使用赋值改变地址

字典的key只能使用不可变类型作为类型

2.创建类

class FirstClass:

    # 类中方法第一个参数必须是self, self就是方法调用对象的引用
    def firstmethond(self, name):
        print("我是 %s 方法" % name)

    def secondmethond(self, name):
        print("我是 %s 方法" % name)


# 创建一个类的实例
first = FirstClass()
first.firstmethond("first")

self 就类似 this 指针

Python中可以在类外通过 .属性名的方法添加属性,但是这种方法不推荐

        如:first.name = "Tom"

初始化方法

        类中的 __init__方法是Python中的内置方法,用于完成对象的创建和在类中定义属性

class FirstClass:

    # 初始化方法,完成对象的对象和属性的赋值
    def __init__(self):

        print("这是一个初始化方法")
        self.name = "Tom"

    def first(self, name):

        print("%s 的名字是 %s" % (self.name, name))


firstObj = FirstClass()
firstObj.first("first")

就是构造方法,同样可以 有参构造,传入参数就行

__del__: 也是内置函数,类似C++中的析构函数,java中由JVM自动完成对象的回收

__str__: 类似java中的toString()方法,自定义对象输出内容,必须返回一个字符串

身份运算符

        is / is not, 用于判断是否是对同一个对象的引用

        Python中 身份运算符 比较的是两个对象的地址; == 比较的是两个对象的值是否相等;Python中针对 None 进行比较时建议使用 身份运算符

私有属性和私有方法

        在属性名或方法前面添加 两个下划线,就是私有的

3. 继承

        继承的语法:

        class 类名(父类名):

                pass

Python中支持多继承,当父类具有同名方法的时候,采用MRO搜索规则

        MRO:可以使用内置函数 __mro__查看函数搜索顺序。

        搜索的时候,首先在当前类中查找,如果有则停止,否则依次找下一个类,直到最后没有找到。

类也可以被看做一个对象,程序运行中被加载一次

类属性:定义在类中__init__以及其他方法外部,通过赋值语句定义类属性。与实例对象没有关系,表示一种全局概念

类方法:在方法定义上面添加修饰器@classmethod, 方法第一个参数必须是cls,作用与self类似

静态方法:当一个方法既不访问成员属性,成员方法,也不访问类属性和类方法,那么可以在方法上面添加 @staticmethod表示静态方法; 通过类名.的方式调用方法

4.单例

        __new__方法:内置的静态方法,在使用类名()创建对象的时候,调用该方法分配空间,并返回对象的引用作为初始化方法__init__的第一个参数self

重写__new__方法,重写规则:return super().__new__(cls)

注意,这里需要手动传递cls

单例实现:

class Singleton(object):

    instance = None  # 记录单例对象的引用
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 判断类属性是否为空对象
        if cls.instance is None:

            # 调用父类方法分配空间,返回对象引用
            cls.instance = super().__new__(cls)

        return cls.instance

    # 用来判断执行一次初始化方法
    def __init__(self):

        if not self.init_flag:

            print("初始化方法被调用")

            self.init_flag = True


sing1 = Singleton()
print(id(sing1))  # 1826555375304
sing2 = Singleton()
print(id(sing2))  # 1826555375304
print(id(Singleton.instance))

5.异常

try:
    # 程序尝试执行的代码
    num = int(input("请输入一个整数:"))

    print(8 / num)

except ZeroDivisionError:
    # 发生异常的代码
    print("输入不能是0")

except ValueError:
    # 其他错误类型捕获
    print("输入应该是个整数")

except Exception as result:
    # 处理其他未知错误
    print("位置错误 %s" % result)

else:
    # 只有当没有发生错误的时候执行
    print("num的值:%d" % num)

finally:
    # 无论是否发生异常,都会执行
    print("程序运行结束")

finally的作用:保证即使有return语句,也会执行这部分代码

def fun():
    try:
        # 程序尝试执行的代码
        num = int(input("请输入一个整数:"))

        print(8 / num)

    except ZeroDivisionError:
        # 发生异常的代码
        print("输入不能是0")

    except ValueError:
        # 其他错误类型捕获
        print("输入应该是个整数")

    except Exception as result:
        # 处理其他未知错误
        print("位置错误 %s" % result)

    else:
        # 只有当没有发生错误的时候执行
        print("num的值:%d" % num)
        return

    finally:
        # 无论是否发生异常,都会执行
        print("程序运行结束")

    print("try...except外部")


fun()

6.文件

        文件写入的访问方式:

file = open("test.txt")

# text = file.read()
# print(text)

while True:
    text = file.readline()
    if not text:
        break;
    print(text, end="")

file.close()

read()方法读取全部内容,readline()读取一行内容 

小文件复制:

file_read = open("test.txt")
file_write = open("text1.txt", "r")

text = file_read.read()
file_write.write(text)

file_read.close()
file_write.close()

Python3中默认编码 UTF-8, Python2中编码ASCII

五、其他补充

5.1 With语句

5.1.1 with和上下文管理器

with 语句用于包装带有使用上下文管理器 定义的方法的代码块的执行。with语句允许在一个代码块周围执行初始化和终结化代码。

  • with语句的上下文管理器

上下文管理器处理进入和退出所需运行时上下文以执行代码块。

 with 语句的执行过程如下:

  1. 对上下文表达式 (在 with_item 中给出的表达式) 求值以获得一个上下文管理器。

  2. 载入上下文管理器的 __exit__() 以便后续使用。

  3. 发起调用上下文管理器的 __enter__() 方法。

  4. 如果 with 语句中包含一个目标,来自 __enter__() 的返回值将被赋值给它。

     

    with语句会保证如果 __enter__() 方法返回时未发生错误,则 __exit__() 将总是被调用。 因此,如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。 参见下面的第 6 步。

  5. 执行语句体。

  6. 发起调用上下文管理器的 __exit__() 方法。 如果语句体的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给 __exit__()。 否则的话,将提供三个 None 参数。

    如果语句体的退出是由异常导致的,并且来自 __exit__() 方法的返回值为假,则该异常会被重新引发。 如果返回值为真,则该异常会被抑制,并会继续执行 with 语句之后的语句。

    如果语句体由于异常以外的任何原因退出,则来自 __exit__() 的返回值会被忽略,并会在该类退出正常的发生位置继续执行。

  • 自定义上下文管理器
class MyContextManager:

    def print(self):
        print(self.__class__)
    
    def __enter__(self):
        print("enter")
        return MyContextManager()

    def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
        print("资源正在销毁")
from MyContextManager import MyContextManager

if __name__ == '__main__':
    with MyContextManager() as mc:   # 返回的对象实例为__enter__的返回值
        mc.print()

 

  • __exit__的参数

在with中手动抛出异常

 如果在执行 with 语句的语句体期间发生了异常,则参数会包含异常的类型、值以及回溯信息。 在其他情况下三个参数均为 None。 

 5.1.2 contextlib 

class contextlib.AbstractAsyncContextManager   一个为实现了 object.__aenter__() 与 object.__aexit__() 的类提供的 abstract base class。 为 object.__aenter__() 提供的一个默认实现是返回 self 而 object.__aexit__() 是一个默认返回 None 的抽象方法。

在方法上使用装饰器:

@contextlib.contextmanager

 这个装饰器是一个生成器函数,可以修饰在一个返回对象的工厂函数上面,不需要在手动创建__exit__和__enter__

@contextmanager
def managed_resource(*args, **kwds):
    # Code to acquire resource, e.g.:
    resource = acquire_resource(*args, **kwds)
    try:
        yield resource  # 生成器返回一个对象
    finally:
        # Code to release resource, e.g.:
        release_resource(resource)

当生成器发生 yield 时,嵌套在 with 语句中的语句体会被执行。 语句体执行完毕离开之后,该生成器将被恢复执行。 如果在该语句体中发生了未处理的异常,则该异常会在生成器发生 yield 时重新被引发。 因此,在装饰的函数内可以使用 try...except...finally 语句来捕获该异常(如果有的话),确保进行了一些异常处理。 

可以在创建对象的时候添加一些实例属性 

总结

        简单了解Python, 整理并不细致,一些概念还是比较模糊

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值