赋值、浅拷贝、深拷贝的区别
1.赋值
赋值是将一个对象的地址赋值给一个变量,让变量指向该地址;无论a,b谁改变,都会改变
alist = [1,2,3]
b = alist
print(a, b)
>>>[1,2,3] [1,2,3]
2.浅拷贝
方法:copy.copy()
浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝
简单理解:ab的子元素改变,另一个变量子元素都会改变;非子元素改变不会影响另外一个变量
import copy
a = [1,2,[3,4]]
b = copy.copy(a)
a.append(5)
print(a, b)
a[2].append(6)
print(a, b)
>>>[1,2,[3,4],5],[1,2,[3,4]]
>>>[1,2,[3,4,6],5],[1,2,[3,4,6]]
3.深拷贝
方法:copy.deepcopy()
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本
简单理解:ab任何元素改变都不会影响
import copy
a = [1,2,[3,4]]
b = copy.deepcopy(a)
a.append(5)
print(a, b)
a[2].append(6)
print(a, b)
>>>[1,2,[3,4],5],[1,2,[3,4]]
>>>[1,2,[3,4,6],5],[1,2,[3,4]]
二、参数传递
1.位置参数
def test1(id ,name):
....
test("1", "zhangsan")
2.关键字参数
def test1(id ,name):
....
test(id="1", name="zhangsan")
3.默认参数
def test1(id=2):
print("111")
test()
4.可变参数
可接受任意数量的位置参数(元组)
def func(*args):
....
func(a, b, c)
5.关键字参数
可接受任意数量的关键字参数(字典)
def func(**kargs):
....
func(a=1, b=2, c=3)
6.解包裹参数
参数args和 *kargs,也可以在函数调用的时候使用,称之为解包
# *args解包
def print_hello(name, sex):
print name, sex
args = ('tanggu', '男')
print_hello(*args)
>>>tanggu 男
# **kargs解包
def print_hello(kargs):
print kargs
kargs = {'name': 'tanggu', 'sex', '男'}
print_hello(**kargs)
>>>{'name': 'tanggu', 'sex', '男'}
主要基本顺序原则:先位置参数,默认参数,包裹位置,包裹关键字
三、列表生成式、普通循环、map
列表生成式、普通循环、map都可以用来生成列表,但是在处理性能上对比,map>列表生成式>普通循环
# 普通循环实现
list1 = []
for x in range(1, 11):
list1.append(x * x)
# 使用列表生成式实现
list2 = [x * x for x in range(1, 11)]
# map实现
list3 = list(map(lambda x : x*x, range(1, 11)))
四、可迭代对象、迭代器、生成器
1.可迭代对象
最简单的解释:可以使用for...in...语句进行循环的对象,就是可迭代对象(Iterable),可以使用isinstance()方法进行判断
from collections import Iterable
type = isinstance('python', Iterable)
print(type)
>>>True
2.迭代器
迭代器指的是可以使用next()方法来回调的对象,可以对可迭代对象使用iter()方法,将其转换为迭代器。
迭代器的优势:
在构建迭代器时,不是将所有的元素一次性的加载,而是等调用next方法时返回元素,所以不需要考虑内存的问题。
迭代器应用场景:
数列的数据规模巨大;数列有规律,但是不能使用列表推导式描述。
#此时temp就是一个迭代器
temp = iter([1, 2, 3])
print(type(temp))
print(next(temp))
>>><class 'list_iterator'>
>>>1
3.生成器
生成器是一种高级迭代器,只是在需要使用next()函数获取值的时候,才会取一个值返回内存开销非常小,但是只能遍历一次
生成器函数:
生成器函数和常规函数都采用def语句进行定义,但是基于yield指令返回一个值
def generator(k):
i = 1
while True:
yield i ** k #使用yield
i += 1
gen = generator(2)
for i in range(4):
sum = 0
sum += next(gen) #相当于每次使用next()之后,generator函数停止了
变量区分
1、全局变量:在模块内、在所有函数外面、在class外面,这就是全局变量。
2、局部变量:在函数内、在class的方法(构造、类方法、静态方法、实例方法)内(变量未加self修饰),这就是局部变量
3、静态变量(类变量):在class内的,但不在class的方法内的,这就是静态变量(类变量)
4、实例变量:在class的方法内的,用self修饰的变量,这就是实例变量
匿名函数
lambda 是一种简洁格式的函数,此表达式不是正常的函数结构,而是属于表达式的类型,一般和其他函数联合使用。 表达式:calc = lambda x, y : x + y calc表示函数名;x,y表示函数参数;x+y表示返回值
1.map函数
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
li = [1,2,3,4,5,6,7,8,9]
print(list(map(lambda x:x*x,li)))
>>>[1, 4, 9, 16, 25, 36, 49, 64, 81]
2.reduce函数
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
from functools import reduce
li = [1,2,3,4,5,6,7,8,9]
print(reduce(lambda x,y:x * y,li))
>>>362880
3.sorted函数
接收一个key函数来实现对可迭代对象进行自定义的排序,key:接受一个函数根据此函数返回的结果进行排序;reverse:排序方向,默认为从小到大,reverse=True为逆向
# 对列表按照绝对值进行排序
li= [-21, -12, 5, 9, 36]
print(sorted(li, key = lambda x:abs(x)))
# 把下面单词以首字母排序
li = ['bad', 'about', 'Zoo', 'Credit']
print(sorted(li, key = lambda x : x[0]))
4.filter函数
filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
# 在一个list中,删掉偶数,只保留奇数
li = [1, 2, 4, 5, 6, 9, 10, 15]
print(list(filter(lambda x:x % 2==1,li)))
>>>[1, 5, 9, 15]
属性私有化
xx: 公有变量
_x: 单前置下划线,私有化属性或方法,禁止通过from modules import *导入,但是类对象和子类可以访问
__xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到),类对象和子类不能访问。通过__类___属性名访问
xx:双前后下划线,用户名字空间的魔法对象或属性。例如:init , __ 尽量不要自定义这种形式的
xx_:单后置下划线,用于避免与Python关键词的冲突
class A:
def __init__(self,name='Andy'):
self._name = name
class B:
def __init__(self,name = 'Jack',age=19):
self.__name = name # 私有属性(变量),只有类对象自己能访问,子类也不能访问
self._age = age # 保护变量,类,及子类对象可以访问
class C(B):
def h(self):
print('hello')
a = A()
b = B()
c = C()
print(a._name) # 输出Adny
print(b._B__name) # 私有属性在类外的访问方式:对象._类__属性名
版权声明:如无特殊说明,文章均为本站原创,转载请注明出处
本文链接:http://zhangyanc.club/article/python_base/
许可协议:署名-非商业性使用 4.0 国际许可协议