Python-基础语法

Python 是一种解释型的面向对象编程的高级语言,本文以 Python3 为准介绍 Python 的基础语法和概念。

文章目录

          • 面向对象编程
          • CPython
          • 数据类型
          • 内存管理/垃圾回收
          • 深拷贝/浅拷贝
          • 函数参数
          • 类和对象
          • 扩展用法
            • 参考文档

面向对象编程

  面向对象是一种编程思想,也是一种技术,区别于面向过程编程,面向对象程序设计中的概念主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。通过这些概念面向对象的思想得到了具体的体现。

  1. 对象(Object) :可以对其做事情的一些东西。一个对象有状态、行为和标识三种属性。
  2. 类(class):一个共享相同结构和行为的对象的集合。类(Class)定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的(它的行为)。举例来说,“狗”这个类会包含狗的一切基础特征,例如它的孕育、毛皮颜色和吠叫的能力。类可以为程序提供模版和结构。一个类的方法和属性被称为“成员”。
  3. 封装(encapsulation):第一层意思:将数据和操作捆绑在一起,创造出一个新的类型的过程。第二层意思:将接口与实现分离的过程。
  4. 继承:类之间的关系,在这种关系中,一个类共享了一个或多个其他类定义的结构和行为。继承描述了类之间的“是一种”关系。子类可以对基类的行为进行扩展、覆盖、重定义。
  5. 组合:既是类之间的关系也是对象之间的关系。在这种关系中一个对象或者类包含了其他的对象和类。组合描述了“有”关系。
  6. 多态:类型理论中的一个概念,一个名称可以表示很多不同类的对象,这些类和一个共同超类有关。因此,这个名称表示的任何对象可以以不同的方式响应一些共同的操作集合。
  7. 动态绑定:也称动态类型,指的是一个对象或者表达式的类型直到运行时才确定。通常由编译器插入特殊代码来实现。与之对立的是静态类型。
  8. 静态绑定:也称静态类型,指的是一个对象或者表达式的类型在编译时确定。
  9. 消息传递:指的是一个对象调用了另一个对象的方法(或者称为成员函数)。
  10. 方法:也称为成员函数,是指对象上的操作,作为类声明的一部分来定义。方法定义了可以对一个对象执行那些操作。
CPython

  CPython是一个默认的、广泛使用的 Python 。当我们从 Python 官方网站下载并安装好 Python3 后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用 C 语言开发的,所以叫CPython,在命令行下运行 Python 就是启动 CPython 解释器。

数据类型

可以使用 type()/isinstance() 函数来查询变量所指的对象类型:

  • Number(数字)
    • 支持 int、float、bool、complex(复数,实部和虚部都是浮点型)
  • String(字符串)
    • 字符串用单引号 ’ 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符
    • 不想让反斜杠发生转义,可以在字符串前面添加一个 r,r'I am handsome.\n'
    • 截取字符串:变量[头下标:尾下标]
    • 字符串相加: str1 + str2
    • 字符串重复: str1*2 (重复2次)
  • Tuple(元组)
    • 元组的元素不能修改,元组写在小括号 () 里,元素之间用逗号隔开。
    • 元组中的元素类型也可以不相同
    • 虽然tuple的元素不可改变,但它可以包含可变的对象,('abc', 1, 3, [1,3,4])
    • 元组元素的引用和字符串类似
  • List(列表)
    • 列表是写在方括号 [] 之间、用逗号分隔开的元素列表
    • 和字符串一样,列表同样可以被索引和截取,同样支持相加+和重复*运算
    • 列表中的元素是可以改变的,操作函数有 append(),pop(),insert(),remove() 等
    • 截取列表:变量[头下标:尾下标:步长]
  • Set(集合)
    • 集合的基本功能是进行成员关系测试和删除重复元素
    • 以使用大括号 { } 或者 set() 函数创建集合
  • Dictionary(字典)
    • 列表是有序的对象集合,字典是无序的对象集合,字典当中的元素是通过键来存取的,而不是通过偏移存取
    • 字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合
    • 键(key)必须使用不可变类型
    • 在同一个字典中,键(key)必须是唯一的

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)

内存管理/垃圾回收

  Python 中,主要依靠 gc(garbage collector)模块的引用计数技术来进行垃圾回收。理解垃圾回收,需要弄清楚三个概念:变量、对象、引用,以num_list = [1, 2, 3]为例:

  • num_list 是一个变量,指我们定义的一个标识符,变量可以指向任何对象,这个对象的类型就是变量的当前类型
  • [1, 2, 3] 是一个列表对象,是有数据类型的,对应内存中的一块区域
  • num_list = [1, 2, 3] 是一个赋值操作,产生了一次[1, 2, 3]对象的引用

  所谓引用计数,就是考虑到 Python 中变量的本质不是内存中一块存储数据的区域,而是*一块内存数据区域的引用。所以 Python 可以给所有对象(内存中的区域)维护一个引用计数的属性,在一个引用被创建或复制的时候,让 Python 把相关对象的引用计数+1;相反当引用被销毁的时候就把相关对象的引用计数-1。当对象的引用计数减到 0 时,自然就可以认为整个 Python 中不会再有变量引用这个对象,所以就可以把这个对象所占据的内存空间释放出来了。

  引用计数技术在每次引用创建和销毁时都要多做一些操作,这可能是一个小缺点,当创建和销毁很频繁的时候难免带来一些效率上的不足。但是其最大的好处就是实时性,其他语言当中,垃圾回收可能只能在一些固定的时间点上进行,比如当内存分配失败的时候进行垃圾回收,而引用计数技术可以动态地进行内存的管理。

  循环引用会导致引用计数失效,何谓循环引用,如下所示。对于下例两个对象而言,虽然已经被 del,但是析构函数没有执行,占用内存没有释放。因为在 del a;delb;时 Python 无法判断调用它们的 del 方法时会不会要用到对方那个对象,比如在进行 b.del() 时可能会用到 b.a 也就是 a,如果在那之前 a 已经被释放,那么就彻底 GG 了。可以使用gc.collect()手动回收。

>>> class A:
...     def __init__(self):
...             print("A born")
...     def __del__(self):
...             print("A dead")
>>> class B:
...     def __init__(self):
...             print("B born")
...     def __del__(self):
...             print("B dead")
>>> a = A()
A born
>>> b = B()
B born
>>> a.b = b
>>> b.a = a
>>> del a
>>> del b
>>> gc.collect()
A dead
B dead
4
>>> gc.collect()
0

  对于整数和短小(256)的字符等,Python 会执行缓存机制,即将这些对象进行缓存,不会为相同的对象分配多个内存空间。

深拷贝/浅拷贝

  在 Python 中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,Python 并没有拷贝这个对象,而只是拷贝了这个对象的引用。

  • 浅层复制和深层复制之间的区别仅与复合对象 (即包含其他对象的对象,如列表或类的实例) 相关:

    • 一个 浅层复制 会构造一个新的复合对象,然后(在可能的范围内)将原对象中找到的 引用 插入其中。
    • 一个 深层复制 会构造一个新的复合对象,然后递归地将原始对象中所找到的对象的 副本 插入。
  • 深度复制操作通常存在两个问题, 而浅层复制操作并不存在这些问题:

    • 递归对象 (直接或间接包含对自身引用的复合对象) 可能会导致递归循环。
    • 由于深层复制会复制所有内容,因此可能会过多复制(例如本应该在副本之间共享的数据)。
函数参数

  Python 中函数的参数也是非常灵活的,用下面的例子介绍。

def enroll(name, gender, age=6, city='Henan'):
	pass
def sum(*number):
	sum = 0
	for n in number:
		sum = sum + n
	return sum
def collect(**meta):
	pass
  • 必选参数
    • enroll() 函数中 name 和 gender 属于必选参数,调用的时候必须传入,否则报错
  • 默认参数,
    • enroll() 函数中 age 和 city 属于默认参数,调用的时候如果不传入,则使用默认值
    • 如果参数列表存在必选参数,默认参数必须在必选参数后面
  • 可选参数
    • sum() 函数中 *number 属于可选参数,调用的时候可以传入 0 个参数,也可以传入多个
    • 调用方式为 sum() 结果是 0 ,调用方式为 sum(1, 2, 3) 结果是 6
    • 也可以直接以 List 或 Tuple 类型作为参数:nums=[1,2,3,4];sum(*nums);结果为 10
  • 关键字参数
    • collect() 函数中 **meta 属于关键字参数,调用的时候可以传入 0 个参数,也可以传入多个
    • 调用方式为 collect(name='starsink', age=30),传入函数后为一个字典 meta = {'name'='starsink','age'=30}
    • 也可以直接把字典传入关键字参数:person={'name'='starsink','age'=30};collect(**person)
类和对象

  对于 Python 的类、对象、方法和 C++/Java 雷同,不在赘述

  • 继承
# Python 支持多继承
class DerivedClassName(Base1, Base2, Base3):
	def __init__(): # 构造函数
		pass
	def __del__():	# 析构函数
		pass
  • 方法重写
class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')
 
class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')
 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
  • 私有属性和方法,双下划线开头的属性和方法即为私有:
class MyClass:
	__private__attrs = 1
	def __private_method():
		pass
  • 运算符重载,最常用的既是字符串转换和加法,例子如下:
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
扩展用法
  • else
count=0
while count>12:
    count += 1
else:
    print('不成立') #当while条件不成立,直接跳到该处输出

c = [1,2]
for i in c:
    print(i)
else:
    print("输出") #当for循环结束会输出该语句

try:
    sum = 1 + 1
except TypeError as e:
    print("报错")
else:
    print("到我这里了") #当 try 块中的语句正常执行完毕会执行该方法。
  • for 创建 List
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print([x * 2 + 10 for x in foo])
  • if 与 for 创建 List
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print([x for x in foo if x % 3 == 0])
  • 正则表达式简单用法
    • re 模块使 Python 语言拥有全部的正则表达式功能,它提供 Perl 风格的正则表达式模式。
    • match 和 search 的区别: re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None;而 re.search 匹配整个字符串,直到找到一个匹配。
    • 常用规则
表达式 描述
. 匹配除换行符以外的所有字符
x? 匹配 0 次或一次 x 字符串
x* 匹配 0 次或多次 x 字符串,但匹配可能的最少次数
x+ 匹配 1 次或多次 x 字符串,但匹配可能的最少次数
.* 匹配 0 次或多次的任何字符
.+ 匹配 1 次或多次的任何字符
[] 匹配符合 [] 内的字符
[^] 匹配不符合 [] 内的字符
[0-9] 匹配所有数字字符
[a-z] 匹配所有小写字母字符
[^0-9] 匹配所有非数字字符
[^a-z] 匹配所有非小写字母字符
^ 匹配字符开头的字符
$ 匹配字符结尾的字符
参考文档

https://www.cnblogs.com/franknihao/p/7326849.html
https://docs.python.org/zh-cn/3/library/copy.html
https://www.runoob.com/perl/perl-regular-expressions.html

你可能感兴趣的:(Python,python)