Fork me on GitHub

py常识

一些基础的python知识。

python特性

1) python是一种解释型语言,这意味着,与C、C++不同,python不需要在运行之前进行编译,它是边运行边解释。
2) python是动态类型化的,这意味着当你声明它们或类似的东西时,你不需要声明变量的类型。你可以x= 1,然后x= “abc”没有错误。
3) python非常适合面向对象编程,因为它允许定义类以及组合和继承。python没有访问修饰符(例C++大的public,private)。
4) 在python中函数是一等对象,这意味着它们可以在运行时动态创建,能赋值给变量或者作为参数传给函数,还能作为函数的返回值。
5) python代码容易上手,开发速度很快,但运行速度通常比编译语言慢。幸运的是,python允许包含基于C的扩展,所以瓶颈可以被优化掉。比如,numpy包就是一个很好的例子,它非常快,因为它所做的很多运算在底部都是用C编写的。

python中的赋值、浅拷贝和深拷贝的区别

1) 对象的赋值
python中对象的赋值实际上是简单的对象引用,也就是说,当你创建一个对象,然后把它复制给另一个变量的时候,python并没有拷贝这个对象,而是拷贝了这个对象的引用。
1

2) 浅拷贝

对于可变对象深浅拷贝

Name 地址
=浅拷贝 值相等 地址相等
copy浅拷贝 值相等 地址不相等
deepcopy深拷贝 值相等 地址不相等

一般引用copy.copy(),可以进行对象的浅拷贝。它复制了对象但对于对象中的元素,依然使用原始的引用。
2
使用copy对a进行浅拷贝,b复制了a的对象,但是b里面的[2, 3, 4]和a里面的[2, 3, 4]其实都是指向同一块内存地址,所以改变了a[1]之后,b里面的b[1]也发生了改变。

对于不可变对象的深浅拷贝
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
2.1
3) 深拷贝
深拷贝需要用copy.deepcopy()进行拷贝。它是复制一个容器对象,以及它里面的所有元素(包含元素的子元素)
3
当对a列表进行深度拷贝之后,b复制了a的对象,但是b里面的[2, 3, 4]和a里面的[2, 3, 4]其实都是指向不同的内存地址。

python中的==is的区别

is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。
4
==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等。
5

线程如何在python中实现

python有一个多线程包threading,可以使用多线程来加快你的代码。但是python有一个叫做Global Interpreter Lock(GIL)的构造。GIL确保只有一个”线程”可以在任何时候执行。
线程获取GIL,做一些工作,然后将GIL传递到下一个线程。这种情况发生得非常快,所以对于人眼而言,它可能看起来像你的线程并行执行,但它们实际上只是轮流使用相同的CPU内核。因此GIL的存在是得python中的多线程无法真正的利用多核的优势来提高性能。
对于IO密集型操作,在等待操作系统返回的时候会释放GIL;再比如爬虫因为有等待的服务器的响应时间,可以利用多线程来加速。但是对于CPU密集型操作,只能通过多进程Multiprocess来加速。

python中的猴子补丁式是什么

考虑下面的例子:
6
猴子补丁:
是一种非常pythonic的用法,即函数再python中可以像使用变量一样对它进行赋值等操作,我们可以再运行时动态替换模块,俗称手法,称为猴子补丁。我们通过对MyClass.f重新赋值,动态的改变了输出的结果。
7

python中的负数index

python中的负数index是用来做什么的?
python中的序列是索引的,它由正数和负数组成。正的数字使用’0’作为第一个索引,’1’作为第二个索引。
负数的索引从’-1’开始,表示序列中的最后一个索引,’-2’作为倒数第二个索引,序列像整数一样向前。
负数索引也可以用来非常方便的切片,比如:
8

类里面的new和init的区别

1) __init__为初始化方法,而__new__方法才是真正的构造函数。只有继承了object的新式类才有__new__
2) ——new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供,__new__必须要有返回值,返回实例化出来的实例。
3) __init__有一个参数self,就是这个__new__返回的实例,先运行__new__然后才运行__init__
4) __init____new__的基础上可以完成一些其它初始的动作,__init__不需要返回值。

python中的参数*args**kwargs

*args是可变参数,一般用来表示我们不能确定多少参数将被传递给函数,或者如果我们想用列表或元组的方式传递给函数。
9
**kwargs是可变关键字参数,当我们不知道有多少关键字参数会传递给一个函数时,或者想把一个字典作为关键字参数时使用。
10
注: *args**kwargs可以同时在函数的定义中,但是*args必须在**kwargs前面。

Your support will encourage me to continue to create!