python 基础笔记

   录

目   录... 3

1章 基本类型... 5

1.1        字符串... 5

1.2        数字... 5

1.3        列表... 5

1.4        字典... 5

1.5        集合... 5

1.6        作用域(转载:)... 5

1.6.1         块级作用域... 5

1.6.2         局部作用域... 6

1.6.3         作用域链... 7

1.6.4         终极版作用域... 7

1.6.5         新浪面试题... 9

1.6.6         补充一个... 9

1.7        总结:... 10

1.7.1         动态类型... 10

1.7.2         内存分配... 12

2章 基本操作... 22

2.1        For 循环... 22

2.1.1. 22

3.2 If 判断... 22

3.3  While 循环... 22

3.4 For语句... 22

3章 函数... 23

3.1        常用函数... 23

3.2        函数定义... 23

3.3        函数传参... 23

3.4        模块... 23

3.4.1         建立模块... 23

3.4.2         导入模块... 23

4章 类... 25

4.1        类的创建与使用... 25

4.1.1         类的定义:... 25

4.1.2         类的继承:... 25

4.1.3         类的多态... 25

4.1        类的导入... 25

5章 文件和异常... 26

5.1        文件操作... 26

5.1.1         读文件... 26

5.1.2         写文件... 26

5.1.3         open文件参数... 26

5.2        异常处理... 26

5.2.1         异常处理模式:... 26

6章 单元测试... 27

6.1        单元测试模式... 27

附   录... 27

使用帮助文档... 27


 

  1. 基本类型
    1. 字符串

1、” ”与 ‘ ’不能同时出现。

2、字符串函数。Upper(), lower(),titile(),lstrip(),rstrip(),strip().  “strTest”.strip()

 

 

    1. 数字
  1.  Python2 ,python3 除法结果不一样 如5/2.  所以应该避免(如可以采用5.0/2))

 

 

    1. 列表

1、列表 即list两个关键点:1)有序(可以通过下标访问,注意下标的访问可以是负数,负数最高值是-size)。 2)可以包含不同类型。

People =[“ren” ,10, ‘vip’,1]

  1. 常用函数:insert(),append,remove, Pop(),sort(),reverse().
    特殊函数:del ,len,Sorted()。
  2. For 循环来遍历列表:
    for one  in People:
       print(one)
    注意缩进,注意不要遗漏冒号。
  3. 数字列表: number=list(range(1,5,2))。不包含5本身。函数(max,min,sum)。
  4. 列表解析:numbers =[number**3 for number in list(range(1,4))]。
  5. 切片技术:
    1)建立列表的副本(如果直接列表复制如list2=list1,则建立的是类似于引用)。
      2)局部列表(可以把列表的一部分复制出来)。
    注意区分列表与下标访问的区别[:].
  6. 元组(tuple):1) 有序(通过下标访问)。2)可以包含不同类型。 3)不可改变。
     
    1. 字典
  1. 字典:1)键,值对。  2)大括号{: , :}.
  2. 建立空字典 dict() ,或{}
    1. 集合
  1. Set: 1)存储的键key ,不能重复
  2. 建立set, 可以用{,} 或 set([ ]),即数组可以用于给set赋值。
    1. 作用域(转载:)
      1. 块级作用域

想想此时运行下面的程序会有输出吗?执行会成功吗?

?

1

2

3

4

5

6

7

8

9

10

11

12

#块级作用域

 

if 1 == 1:

    name = "lzl"

 

print(name)

 

 

for i in range(10):

    age = i

 

print(age)

我们先看下执行结果

?

1

2

3

4

5

C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py

lzl

9

 

Process finished with exit code 0

代码执行成功,没有问题;在Java/C#中,执行上面的代码会提示name,age没有定义,而在Python中可以执行成功,这是因为在Python中是没有块级作用域的,代码块里的变量外部可以调用,所以可运行成功;

 

      1. 局部作用域

回顾之前学过的知识,我们学函数的时候,函数是个单独的作用域,Python中没有块级作用域,但是有局部作用域;看看下面的代码

?

1

2

3

4

5

6

#局部作用域

 

def  func():

    name = "lzl"

 

print(name)

运行这段代码,想想会不会有输出?

?

1

2

3

4

Traceback (most recent call last):

  File "C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py", line 23, in

    print(name)

NameError: name 'name' is not defined

运行报错,我相信这个大家都能理解,name变量只在func()函数内部中生效,所以在全局中是没法调用的;对上面代码做个简单调整,再看看结果如何?

?

1

2

3

4

5

6

7

#局部作用域

 

def  func():

    name = "lzl"

 

func()          #执行函数

print(name)

对之前的代码添加了一句代码,在变量name打印之前,执行了一下函数,此时打印会不会有变化?

?

1

2

3

4

Traceback (most recent call last):

  File "C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py", line 23, in

    print(name)

NameError: name 'name' is not defined

执行依然报错,还是回到刚才那句话:即使执行了一下函数,name的作用域也只是在函数内部,外部依然无法进行调用;把前两个知识点记住,接下来要开始放大招了

 

      1. 作用域链

对函数做下调整,看看下面的代码执行结果如何?

?

1

2

3

4

5

6

7

8

9

10

#作用域链

 

name = "lzl"

def f1():

    name = "Eric"

    def f2():

        name = "Snor"

        print(name)

    f2()

f1()

学过函数,肯定知道最后f1()执行完会输出Snor;我们先记住一个概念,Python中有作用域链,变量会由内到外找,先去自己作用域去找,自己没有再去上级去找,直到找不到报错 

      1. 终极版作用域

好,铺垫了够了,终极版的来了~~

?

1

2

3

4

5

6

7

8

9

10

11

12

#终极版作用域

 

name = "lzl"

 

def f1():

    print(name)

 

def f2():

    name = "eric"

    f1()

 

f2()

想想最后f2()执行结果是打印“lzl”呢,还是打印“eric”?记住自己的答案,现在先不把答案贴出来,先看看下面这段代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#终极版作用域

 

name = "lzl"

 

def f1():

    print(name)

 

def f2():

    name = "eric"

    return f1

 

ret = f2()

ret()

 

#输出:lzl

执行结果为“lzl”,分析下上面的代码,f2()执行结果为函数f1的内存地址,即ret=f1;执行ret()等同于执行f1(),执行f1()时与f2()没有任何关系,name=“lzl”与f1()在一个作用域链,函数内部没有变量是会向外找,所以此时变量name值为“lzl”;理解了这个,那么刚才没给出答案的那个终极代码你也知道答案了

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#终极版作用域

 

name = "lzl"

 

def f1():

    print(name)

 

def f2():

    name = "eric"

    f1()

 

f2()

 

# 输出:lzl

是的,输出的是“lzl”,记住在函数未执行之前,作用域已经形成了,作用域链也生成了

 

      1. 新浪面试题

?

1

li = [lambda :x for x in range(10)]

判断下li的类型?li里面的元素为什么类型?

?

1

2

3

4

5

print(type(li))

print(type(li[0]))

 

#

#

可以看到li为列表类型,list里面的元素为函数,那么打印list里面第一个元素的返回值,此时返回值为多少?

?

1

2

3

4

5

6

7

8

#lambada 面试题

 

li = [lambda :x for x in range(10)]

 

res = li[0]()

print(res)

 

#输出:9

li第一个函数的返回值为9还不是0,记住:函数在没有执行前,内部代码不执行;博客里面的代码可以自己练练,加深下印象

 

      1. 补充一个

瞅瞅下面的代码:

?

1

2

3

4

5

6

7

8

def f1():

    def f2():

        print(name)

    name = 'Jefrey'

    return f2()

f1()

 

# Jefrey

函数内部的变量(name),优先去f2函数内部找,且只能在print(name)之前去定义;如果没有,跳出当前函数一层,去外部找变量定义f1内部去找,跳出当前f2函数找变量定义时,无论变量定义在函数f2之前还是之后都是可以的;当外部f1有多个定义时,如何执行?

?

1

2

3

4

5

6

7

8

9

10

def f1():

    name = 'lzl'

    name = 'lianzhilei'

    def f2():

        print(name)

    name = 'Jefrey'

    f2()

f1()

 

# Jefrey

当外部函数里有多个变量定义时,找f2()执行时,执行最近上面的变量的值

 

 

    1. 总结:
      1. 动态类型

动态类型(dynamic typing)是Python另一个重要的核心概念。我们之前说过,Python的变量(variable)不需要声明,而在赋值时,变量可以重新赋值为任意值。这些都与动态类型的概念相关。

        1. 动态类型

在我们接触的对象中,有一类特殊的对象,是用于存储数据的。常见的该类对象包括各种数字,字符串,表,词典。在C语言中,我们称这样一些数据结构为变量。而在Python中,这些是对象。

对象是储存在内存中的实体。但我们并不能直接接触到该对象。我们在程序中写的对象名,只是指向这一对象的引用(reference)

 

引用和对象分离,是动态类型的核心。引用可以随时指向一个新的对象:

a = 3

a = 'at'

第一个语句中,3是储存在内存中的一个整数对象。通过赋值,引用a指向对象3

第二个语句中,内存中建立对象‘at’,是一个字符串(string)。引用a指向了'at'。此时,对象3不再有引用指向它。Python会自动将没有引用指向的对象销毁(destruct),释放相应内存。

(对于小的整数和短字符串,Python会缓存这些对象,而不是频繁的建立和销毁。)

 

a = 5

b = a

a = a + 2

再看这个例子。通过前两个句子,我们让a,b指向同一个整数对象5(b = a的含义是让引用b指向引用a所指的那一个对象)。但第三个句子实际上对引用a重新赋值,让a指向一个新的对象7。此时a,b分别指向不同的对象。我们看到,即使是多个引用指向同一个对象,如果一个引用值发生变化,那么实际上是让这个引用指向一个新的引用,并不影响其他的引用的指向。从效果上看,就是各个引用各自独立,互不影响。

 

其它数据对象也是如此:

L1 = [1,2,3]

L2 = L1

L1 = 1

 

但注意以下情况

L1 = [1,2,3]

L2 = L1

L1[0] = 10

print L2

在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。

原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

(与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)

 

列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。

而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)

我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

 

        1. 从动态类型看函数的参数传递

函数的参数传递,本质上传递的是引用。比如说:

 

def f(x):

    x = 100

    print x

 

a = 1

f(a)

print a

 

参数x是一个新的引用,指向a所指的对象。如果参数是不可变(immutable)的对象,a和x引用之间相互独立。对参数x的操作不会影响引用a。这样的传递类似于C语言中的值传递。

 

如果传递的是可变(mutable)的对象,那么改变函数参数,有可能改变原对象。所有指向原对象的引用都会受影响,编程的时候要对此问题留心。比如说:

 

def f(x):

    x[0] = 100

    print x

 

a = [1,2,3]

f(a)

print a

 

 

动态类型是Python的核心机制之一。可以在应用中慢慢熟悉。

 

        1. 总结

引用和对象的分离,对象是内存中储存数据的实体,引用指向对象。

可变对象,不可变对象

函数值传递

 

      1. 内存分配

语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征。这里以Python语言为例子,说明一门动态类型的、面向对象的语言的内存管理方式。

 

        1. 对象的内存使用

赋值语句是语言最常见的功能了。但即使是最简单的赋值语句,也可以很有内涵。Python的赋值语句就很值得研究。

a = 1

整数1为一个对象。而a是一个引用。利用赋值语句,引用a指向对象1。Python是动态类型的语言(参考动态类型),对象与引用分离。Python像使用“筷子”那样,通过引用来接触和翻动真正的食物——对象。

 

 

 引用和对象

 

为了探索对象在内存的存储,我们可以求助于Python的内置函数id()。它用于返回对象的身份(identity)。其实,这里所谓的身份,就是该对象的内存地址

a = 1

 

print(id(a))

print(hex(id(a)))

在我的计算机上,它们返回的是:

11246696
'0xab9c68'

分别为内存地址的十进制和十六进制表示。

 

在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象。

a = 1

b = 1

 

print(id(a))

print(id(b))

上面程序返回

11246696

11246696

可见a和b实际上是指向同一个对象的两个引用。

 

为了检验两个引用指向同一个对象,我们可以用is关键字。is用于判断两个引用所指的对象是否相同。

 

# True

a = 1

b = 1

print(a is b)

 

# True

a = "good"

b = "good"

print(a is b)

 

# False

a = "very good morning"

b = "very good morning"

print(a is b)

 

# False

a = []

b = []

print(a is b)

 

上面的注释为相应的运行结果。可以看到,由于Python缓存了整数和短字符串,因此每个对象只存有一份。比如,所有整数1的引用都指向同一对象。即使使用赋值语句,也只是创造了新的引用,而不是对象本身。长的字符串和其它对象可以有多个相同的对象,可以使用赋值语句创建出新的对象。

 

在Python中,每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。

我们可以使用sys包中的getrefcount(),来查看某个对象的引用计数。需要注意的是,当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。

 

from sys import getrefcount

 

a = [1, 2, 3]

print(getrefcount(a))

b = a

print(getrefcount(b))

 

由于上述原因,两个getrefcount将返回2和3,而不是期望的1和2。

容器对象:

 

 

        1. 对象引用对象

Python的一个容器对象(container),比如表、词典等,可以包含多个对象。实际上,容器对象中包含的并不是元素对象本身,是指向各个元素对象的引用。

我们也可以自定义一个对象,并引用其它对象:

 

class from_obj(object):

    def __init__(self, to_obj):

        self.to_obj = to_obj

 

b = [1,2,3]

a = from_obj(b)

print(id(a.to_obj))

print(id(b))

 

可以看到,a引用了对象b。

 

对象引用对象,是Python最基本的构成方式。即使是a = 1这一赋值方式,实际上是让词典的一个键值"a"的元素引用整数对象1。该词典对象用于记录所有的全局引用。该词典引用了整数对象1。我们可以通过内置函数globals()来查看该词典。

 

当一个对象A被另一个对象B引用时,A的引用计数将增加1。

 

from sys import getrefcount

 

a = [1, 2, 3]

print(getrefcount(a))

 

b = [a, a]

print(getrefcount(a))

 

由于对象b引用了两次a,a的引用计数增加了2。

 

容器对象的引用可能构成很复杂的拓扑结构。我们可以用objgraph包来绘制其引用关系,比如

 

x = [1, 2, 3]

y = [x, dict(key1=x)]

z = [y, (x, y)]

 

import objgraph

objgraph.show_refs([z], filename='ref_topo.png')

 

 

 

 

 

 

 

objgraph是Python的一个第三方包。安装之前需要安装xdot。

sudo apt-get install xdot

sudo pip install objgraph

objgraph官网

 

两个对象可能相互引用,从而构成所谓的引用环(reference cycle)。

a = []

b = [a]

a.append(b)

即使是一个对象,只需要自己引用自己,也能构成引用环。

a = []

a.append(a)

print(getrefcount(a))

引用环会给垃圾回收机制带来很大的麻烦,我将在后面详细叙述这一点。

 

        1. 引用减少

某个对象的引用计数可能减少。比如,可以使用del关键字删除某个引用:

 

from sys import getrefcount

 

a = [1, 2, 3]

b = a

print(getrefcount(b))

 

del a

print(getrefcount(b))

 

 

del也可以用于删除容器元素中的元素,比如:

a = [1,2,3]

del a[0]

print(a)

 

 

如果某个引用指向对象A,当这个引用被重新定向到某个其他对象B时,对象A的引用计数减少:

 

from sys import getrefcount

a = [1, 2, 3]

b = a

print(getrefcount(b))

 

a = 1

print(getrefcount(b))

 

 

 

        1. 垃圾回收

吃太多,总会变胖,Python也是这样。当Python中的对象越来越多,它们将占据越来越大的内存。不过你不用太担心Python的体形,它会乖巧的在适当的时候“减肥”,启动垃圾回收(garbage collection),将没用的对象清除。在许多语言中都有垃圾回收机制,比如Java和Ruby。尽管最终目的都是塑造苗条的提醒,但不同语言的减肥方案有很大的差异 (这一点可以对比本文和Java内存管理与垃圾回收

)。

 

从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。比如下面的表:

a = [1, 2, 3]

del a

del a后,已经没有任何引用指向之前建立的[1, 2, 3]这个表。用户不可能通过任何方式接触或者动用这个对象。这个对象如果继续待在内存里,就成了不健康的脂肪。当垃圾回收启动时,Python扫描到这个引用计数为0的对象,就将它所占据的内存清空。

 

然而,减肥是个昂贵而费力的事情。垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。如果内存中的对象不多,就没有必要总启动垃圾回收。所以,Python只会在特定条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。

我们可以通过gc模块的get_threshold()方法,查看该阈值:

import gc

print(gc.get_threshold())

返回(700, 10, 10),后面的两个10是与分代回收相关的阈值,后面可以看到。700即是垃圾回收启动的阈值。可以通过gc中的set_threshold()方法重新设置。

 

我们也可以手动启动垃圾回收,即使用gc.collect()

 

        1. 分代回收

Python同时采用了分代(generation)回收的策略。这一策略的基本假设是,存活时间越久的对象,越不可能在后面的程序中变成垃圾。我们的程序往往会产生大量的对象,许多对象很快产生和消失,但也有一些对象长期被使用。出于信任和效率,对于这样一些“长寿”对象,我们相信它们的用处,所以减少在垃圾回收中扫描它们的频率。

 

Python将所有的对象分为0,1,2三代。所有的新建对象都是0代对象。当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象。垃圾回收启动时,一定会扫描所有的0代对象。如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。

这两个次数即上面get_threshold()返回的(700, 10, 10)返回的两个10。也就是说,每10次0代垃圾回收,会配合1次1代的垃圾回收;而每10次1代的垃圾回收,才会有1次的2代垃圾回收。

同样可以用set_threshold()来调整,比如对2代对象进行更频繁的扫描。

import gc

gc.set_threshold(700, 10, 5)

 

        1. 孤立的引用环

引用环的存在会给上面的垃圾回收机制带来很大的困难。这些引用环可能构成无法使用,但引用计数不为0的一些对象。

 

a = []

b = [a]

a.append(b)

 

del a

del b

 

上面我们先创建了两个表对象,并引用对方,构成一个引用环。删除了a,b引用之后,这两个对象不可能再从程序中调用,就没有什么用处了。但是由于引用环的存在,这两个对象的引用计数都没有降到0,不会被垃圾回收。

 

孤立的引用环

 

为了回收这样的引用环,Python复制每个对象的引用计数,可以记为gc_ref。假设,每个对象i,该计数为gc_ref_i。Python会遍历所有的对象i。对于每个对象i引用的对象j,将相应的gc_ref_j减1。

 

 

遍历后的结果

 

在结束遍历后,gc_ref不为0的对象,和这些对象引用的对象,以及继续更下游引用的对象,需要被保留。而其它的对象则被垃圾回收。

 

        1. 总结

Python作为一种动态类型的语言,其对象和引用分离。这与曾经的面向过程语言有很大的区别。为了有效的释放内存,Python内置了垃圾回收的支持。Python采取了一种相对简单的垃圾回收机制,即引用计数,并因此需要解决孤立引用环的问题。Python与其它语言既有共通性,又有特别的地方。对该内存管理机制的理解,是提高Python性能的重要一步。

2 XXXX

 

 

  1. 基本操作
    1. For 循环
      1.  

For   iterating_var   in   sequence:

     statements(s)

 else:

     statements(s)

 注意 1)sequence 可以为字符串,列表,元组等序列

  1.  iterating_var 取值自sequence

3.2 If 判断

    if  contion:

        statements(s)

    elif contion:

        statements(s)

    else:

        statements(s)

 注意 1) and , or  ,in ,not in.

      2)  布尔表达式:True,False 首写字母大写。

      3) if 可以判断列表是否为空

3.3  While 循环

3.4 For语句

[ expression for x in X [if condition]

             for y in Y [if condition]

             ...

             for n in N [if condition] ]

 

  1. 函数
    1. 常用函数

输文本,str = input(”please input text”)

输出   print()

int 转string  :str()

string转int :int()

type: 输出地址。

Help: 获取帮助。

Sys.getsizeof():  import sys 获取的一个对象所占用的字节的大小。

    1. 函数定义

1 、我们在使用def 关键字定义一个函数时,其后必须跟有函数名和包括形式参数的圆括号。函数体的下一行开始,必须是缩进的。函数体的第一行可以是字符串,这个字符串就是文档字符串(documentation string),通常也称作:docstring。

   def   fun_name():

         “””doc string”””

 

          #TO DO

 

2、注释: 单行注释#。可以设置注释本身的编码方式 #coding=utf-8。

          多行注释“”

 

    1. 函数传参
  1. 顺序传递:顺序传递参数未传统的传递方式,将实参安装形参的默认顺序传入。
  2. 关键字传递:在传递参数的时候,指定关键字。在实参中将名称和值关联起来。因此可以忽略顺序,向函数传递实参时不会混淆。 Fun_test(paraYear=18,paraName=”beck”)
  3. 函数中也可以使用默认值,默认值得顺序,同样遵循从右到左的顺序,从右边第一个参数开始。
  4. 传递列表(list),字典(dic)。在函数中对其通过形参传递进来的list或dic成员的修改,会永久性影响到传递进来的参数(实参),如果希望不被影响,可以传递切片。
  5.  传递任意数量的实参:在形参前添加*,创建了1个空元组,可以传递任意个数的参数(注意这些参数无法被更改赋值,因为是元组):def fun_Npara(*toppings)   ; 在形参前添加**,创建1个空的字典,可以传递任意个数的参数(以dic字典方式)。
     
    1. 模块
      1. 建立模块

       建立另外1个后缀为.py 的文件,该文件即为1个模块。

      1. 导入模块

 

  1. 模式1:
    Import module_name
    Mudule_name.func1()
  2. 模式2:
    From module_name import func1,func2
    Func1()
    Func2(para1)
  3. 模式3:
    From module_name import* (不提倡使用)
    Func1()
    ……
  4. 别名 as
  5. 不同文件夹:
    让子目录成为1个包---在该目录下建立1个__init__.py:

__all__ 列表中的子模块和子包导入到当前作用域中来(用于其他模块模糊导入)

 

package

  |- subpackage1

      |- __init__.py

      |- a.py

  |- subpackage2

      |- __init__.py

      |- b.py

 

(1)在subpackage1 中的__init__.py: __all__=[“a”]

则在subpackage2中的b.py 中:加入路径:

from os import path  

d = path.abspath("..")

sys.path.append(d)

from subpackage1 import *

a.fun_test()

(2)有以下几种导入方式:

import subpackage1.a # 将模块subpackage.a导入全局命名空间,例如访问a中属性时用subpackage1.a.attr

from subpackage1 import a # 将模块a导入全局命名空间,例如访问a中属性时用a.attr_a

from subpackage.a import attr_a # 将模块a的属性直接导入到命名空间中,例如访问a中属性时直接用attr_a

 

    1. 类的创建与使用
      1. 类的定义:

       Class Myclass(object):

              __init__(self,para1):

                 ……

              __del__(selft.para1..):

                 ….

              attrA = 4

              __attrB=15

              __attrC__ =16

1: 构造函数__init__ :实例化时自动执行。

析构函数__del__: 删除时自动执行。

2: 1):只有双划线在前面的,为私有属性或方法。

2):前面和后面均有双划线的,一般是系统属性(不建议这样命名,__attrC__),但可以被外部访问。

3: 类明后括号中为继承的类,默认继承自(object)。

4: 在类外修改类中的属性的值,所有对象中的值均会被修改。而修改对象的值,不会影响到类。

5:  如果需要建立实例的类不要忘记传入参数self。如果直接用类访问函数(不通过实例),则可以不用传入。

      1. 类的继承:

1: 类的继承,在类后面括号中填入父类。

2: 子类调用父类,采用super()。

3: 子类不会自动调用父类的构造函数__init__,必须在子类中显示调用。

4: 类CA 的实例,可以用于类CB的成员属性。注意属性在声明时即被定义(也就是会直接建立实例,会执行该实例的构造函数。独立属性,注意这个构造函数在CB本身构造函数之前执行)

 

      1. 类的多态

      因python并不进行变量的类型校验。因为可以使用同一变量访问不同对象的函数接口。

       Instance = getClassInstance()

       If  hasattr(Instance, “fun1”):

          Instance.fun1()

 

    1. 类的导入
  1. From module import className1,className2
  2. From module import *

 

 

 

 

  1. 文件和异常
    1. 文件操作
      1. 读文件

with open("test.txt") as file_object:

    contens = file_object.read();

print(contens)

 

  1. With关键字的说明:
    with语句时用于对try except finally 的优化,让代码更加美观,
     
    例如常用的开发文件的操作,用try except finally 实现:
     
    复制代码
    f=open('file_name','r')
    try:
        r=f.read()
    except:
        pass
    finally:
    f.close()

2)读文件常用函数: read(),  for line in file_object,  readlines()

      1. 写文件
  1. write函数
      1. open文件参数

1) open(strfile_name, ‘r’),  ‘r’: 读,’w’: 覆盖写   ‘a’:追加写

 

    1. 异常处理
      1. 异常处理模式:

      try

            *********

      Except FileNotFoundError:

            **********

      Else:

           **************

 

  1. 单元测试
    1. 单元测试模式

import unittest

from name_function import get_fullname

 

class CNameTestCase(unittest.TestCase):

    """name_function.py"""

    def test_name(self):

        fullname = get_fullname("ren","hui")

        self.assertEqual(fullname,"ren_hui")

 

    def test_empty(self):

        print("empty test")

        self.assertEqual("1","wewe")

 

    def test_empty1(self):

        print("more empty test")

 

unittest.main()

 

  1. 导入 unittest 模块
  2. 单元测试类继承自 unittest.TestCase
  3. 类中的单元测试函数已 test开头(可以自动运行)
  4. 调用 unitetest.main 执行

 

附  

使用帮助文档

  1. 使用help:
    Help():help(object) for help about object

2)使用 dir 获取模块,类(包含其基类的属性信息)

Dir():list of strings

  1. 使用__doc__. 

Print(*.__doc__) : 打印注释。

  1. python 自带模块生产帮助文档:python -m pydoc -p 6666
    通过浏览器http://localhost:6666/

你可能感兴趣的:(python)