Python基础记录

深拷贝和浅拷贝

深拷贝与浅拷贝的区别在于,当从原本的list复制出的list之后,修改其中的任意一个是否会对另一个造成影响,即这两个list在内存中是否储存在同一个区域,这也是区分深拷贝与浅拷贝的重要依据。

浅拷贝:A变量变化,B变量跟着改变
深拷贝:A变量变化,B变量不受影响

copy():对于list的第一层,是实现了深拷贝,但对于嵌套的list,仍然是浅拷贝。

old = [1,[1,2,3],3]
new = old.copy()
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] =3
print('After:')
print(old)
print(new)

output:
Before:
[1, [1, 2, 3], 3]
[1, [1, 2, 3], 3]
After:
[1, [3, 2, 3], 3]   #对于list的第一层(非嵌套层),实现了深拷贝,对于嵌套的list,仍然是浅拷贝。
[3, [3, 2, 3], 3]

通过for循环遍历,将元素一个个添加到新列表中。这也是一个浅拷贝方法,只对第一层实现深拷贝。

通过使用[:]切片,可以浅拷贝整个列表。同样的,只对第一层实现深拷贝。

完全深拷贝的实现:
如果用deepcopy()方法,则无论多少层,无论怎样的形式,得到的新列表都是和原来无关的,这是最安全最有效的方法。

import copy
old = [1,[1,2,3],3]
new = copy.deepcopy(old)
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)

output:
Before:
[1, [1, 2, 3], 3]
[1, [1, 2, 3], 3]
After:
[1, [1, 2, 3], 3]
[3, [3, 2, 3], 3]

列表

列表方法

list.append(obj)  
在列表末尾添加新的对象
list.count(obj)   
统计某个元素在列表中出现的次数  
list.extend(seq)  
在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)  
list.index(obj)  
从列表中找出某个值第一个匹配项的索引位置  
list.insert(index, obj)  
将对象插入列表  
list.pop([index=-1])  
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值  
list.remove(obj)  
移除列表中某个值的第一个匹配项  
list.reverse()  
反向列表中元素  
list.sort( key=None, reverse=False)  
对原列表进行排序  
list.clear()  
清空列表  
list.copy()  
复制列表  

模块

一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
当我们使用import语句的时候,Python解释器是怎样找到对应的文件的呢?这就涉及到Python的搜索路径,搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。查看Python搜索路径:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>> 

from … import
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。

from … import *
把一个模块的所有内容全都导入到当前的命名空间,但是那些由单下划线(_)开头的私有函数或变量不在此例。大多数情况, Python程序员不使用这种方法。为引入的其它来源的命名,很可能覆盖了已有的定义。如果不同模块包含了函数名相同的函数,或者是与自己编写得函数名相同将会导致混乱,而且在 debug 时还不容易发现。

这里给出了一种可能的包结构(在分层的文件系统中):

sound/                          顶层包
  __init__.py               初始化 sound 包
  formats/                  文件格式转换子包
          __init__.py         有__init__.py才被认为是一个包
          wavread.py
          wavwrite.py
          aiffread.py
          aiffwrite.py
          auread.py
          auwrite.py
          ...
  effects/                  声音效果子包
          __init__.py
          echo.py          echo模块
          surround.py    surround模块
          reverse.py       reverse模块
          ...
  filters/                  filters 子包
          __init__.py
          equalizer.py
          vocoder.py
          karaoke.py
          ...

在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

import sound.effects.echo
# 这将会导入子模块:sound.effects.echo。 他必须使用全名去访问:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

#还有一种导入子模块的方法是:
from sound.effects import echo
#这同样会导入子模块: echo,并且他不需要那些冗长的前缀,所以他可以这样使用:
echo.echofilter(input, output, delay=0.7, atten=4)

#还有一种变化就是直接导入一个函数或者变量
from sound.effects.echo import echofilter
#这种方法会导入子模块: echo,并且可以直接使用他的 echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)

注意当使用from package import item这种形式的时候,对应的item既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
如果使用形如import item.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。

关于导入模块,自己写的程序,自己也可以把它保存下来,以后需要的时候导入使用,例如下面所示。
我有个代码名称为 test1.py,它的所在路径为 D:\test 下面。那我只需要完成以下步骤就可以把它作为模块 import 到其他代码中了。

import sys
sys.path.append("D:\\test")

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法:类中定义的函数。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

class MyClass:

    i = 12345       #类变量
    def f(self):
        return 'hello world'

类有一个名为__init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用,像下面这样:

def __init__(self):
    self.data = []

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。

class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问,只能在类内部访问,以两个下划线打头
    __weight = 0

类的继承,Python也支持多继承

class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

s = student('ken',10,60,3)
s.speak()

方法重写,如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法。

类的私有属性(两个下划线开头):__private_attrs:声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的私有方法(两个下划线开头):__private_method:声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
类的专有方法(魔法方法)(前后两个下划线):

__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方

但是以单个下划线打头的函数或变量为相对此模块本身为私有的,外界无法调用。

静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。
逻辑上类方法应当只被类调用,实例方法实例调用,静态方法两者都能调用。主要区别在于参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是 cls 引用作为参数。

获取帮助

import math
dir(math)    #查看模块下所有函数
['__doc__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'acos',
 'acosh',
 'asin',
 'asinh',
 'atan',
 'atan2',
 'atanh',
...


help(math.log)       #help查看帮助
Help on built-in function log in module math:

log(...)
    log(x[, base])

    Return the logarithm of x to the given base.
    If the base not specified, returns the natural logarithm (base e) of x.


math.log.__doc__      #查看函数文档字符串
log(x[, base])

Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.

import random
print(random.__file__)     #查看源码的位置
C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\random.py

Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问。

常用函数

dec=12
bin(dec))    #十进制转二进制0b1100
oct(dec))   #十进制转八进制0o14
hex(dec))     #十进制转十六进制0xc

ord()    #字符转化为ASCII码
chr()     #ASCII码转化为字符

str.upper()       # 把所有字符中的小写字母转换成大写字母
str.lower()         # 把所有字符中的大写字母转换成小写字母
str.capitalize()     # 把第一个字母转化为大写字母,其余小写
str.title()        # 把每个单词的第一个字母转化为大写,其余小写

猜你喜欢

转载自www.cnblogs.com/keegentang/p/11546096.html