赋值、浅拷贝、深拷贝的区别

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 国际许可协议