python 基础总结

1 hello world

#-*- coding:utf-8 -*- #这个是为了说明文件的编码方式,不可缺少,也可以用#coding=utf-8

#单行注释
print("hello world")

#多行注释'''
'''
print("hello world")
print("hello world")

'''

优点

  • 简单
  • 易学
  • 免费、开源
  • 高层语言————当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节。
  • 可移植性————由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。
  • 解释性————这一点需要一些解释。一个用编译性语言比如C或C++写的程序可以从源文件(即C或C++语言)转换到一个你的计算机使用的语言(二进制代码,即0和1)。这个过程通过编译器和不同的标记、选项完成。当你运行你的程序的时候,连接/转载器软件把你的程序从硬盘复制到内存中并且运行。而Python语言写的程序不需要编译成二进制代码。你可以直接从源代码运行程序。在计算机内部,Python解释器把源代码转换成称为字节码的中间形式,然后再把它翻译成计算机使用的机器语言并运行。事实上,由于你不再需要担心如何编译程序,如何确保连接转载正确的库等等,所有这一切使得使用Python更加简单。由于你只需要把你的Python程序拷贝到另外一台计算机上,它就可以工作了,这也使得你的Python程序更加易于移植。
  • 面向对象
  • 可扩展性————如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。
  • 丰富的库
  • 规范的代码

基础知识

  • 输出与格式化:print("我的姓名是%s,年龄是%d"%(name,age))

  • 输入:password = input("请输入密码:") 或者python2的password = raw_input("请输入密码:")

  • 常用的数据类型转换

    函数 说明
    int(x [,base ]) 将x转换为一个整数
    long(x [,base ]) 将x转换为一个长整数
    float(x ) 将x转换到一个浮点数
    complex(real [,imag ]) 创建一个复数
    str(x ) 将对象 x 转换为字符串
    repr(x ) 将对象 x 转换为表达式字符串
    eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象
    tuple(s ) 将序列 s 转换为一个元组
    list(s ) 将序列 s 转换为一个列表
    chr(x ) 将一个整数转换为一个字符
    unichr(x ) 将一个整数转换为Unicode字符
    ord(x ) 将一个字符转换为它的整数值
    hex(x ) 将一个整数转换为一个十六进制字符串
    oct(x ) 将一个整数转换为一个八进制字符串
  • 逻辑运算符 and or not

  • 双引号或者单引号中的数据,就是字符串

  • 列表与元组支持下标索引好理解,字符串实际上就是字符的数组,所以也支持下标索引。所以可以直接获取字母 ,如print(name[0])

  • 字符串切片,是指对操作的对象截取其中一部分的操作,如print(name[0:3]) # 取 下标0~2 的字符 print(name[1:-1]) # 取 下标为1开始 到 最后第2个 之间的字符

  • 字符串常用操作

方法 说明 示例
find 检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则返回-1 mystr.find(str, start=0, end=len(mystr))
index 跟find()方法一样,只不过如果str不在 mystr中会报一个异常. mystr.index(str, start=0, end=len(mystr))
count 返回 str在start和end之间 在 mystr里面出现的次数 mystr.count(str, start=0, end=len(mystr))
replace 把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次 mystr.replace(str1, str2, mystr.count(str1))
split 以 str 为分隔符切片 mystr,如果 maxsplit有指定值,则仅分隔 maxsplit 个子字符串 mystr.split(str=" ", 2)
capitalize 把字符串的第一个字符大写 mystr.capitalize()
title 把字符串的每个单词首字母大写
startswith 检查字符串是否是以 obj 开头, 是则返回 True,否则返回 False mystr.startswith(obj)
endswith 检查字符串是否以obj结束,如果是返回True,否则返回 False. mystr.endswith(obj)
lower 转换 mystr 中所有大写字符为小写 mystr.lower()
upper 转换 mystr 中的小写字母为大写 mystr.upper()
ljust 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串 mystr.ljust(width)
rjust 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串 mystr.rjust(width)
center 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 mystr.center(width)
lstrip 删除 mystr 左边的空白字符 mystr.lstrip()
rstrip 删除 mystr 字符串末尾的空白字符 mystr.rstrip()
strip 删除mystr字符串两端的空白字符
rfind 类似于 index(),不过是从右边开始. mystr.rindex( str, start=0,end=len(mystr))
partition 把mystr以str分割成三部分,str前,str和str后 mystr.partition(str)
rpartition 类似于 partition()函数,不过是从右边开始. mystr.rpartition(str)
splitlines 按照行分隔,返回一个包含各行作为元素的列表 mystr.splitlines()
isalpha 如果 mystr 所有字符都是字母 则返回 True,否则返回 False mystr.isalpha()
isdigit 如果 mystr 只包含数字则返回 True 否则返回 False. mystr.isdigit()
isalnum 如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False mystr.isalnum()
isspace 如果 mystr 中只包含空格,则返回 True,否则返回 False. mystr.isspace()
join mystr 中每个字符后面插入str,构造出一个新的字符串 str.join(mystr)
  • 列表 testList = [1, 'a']
  • 列表常用方法
方法 说明
append 向列表添加元素
extend 将另一个集合中的元素逐一添加到列表中
insert insert(index, object) 在指定位置index前插入元素object
修改元素 通过下标来确定要修改的是哪个元素,然后才能进行修改
in(存在) 如果存在那么结果为true,否则为false
not in(不存在) 如果不存在那么结果为true,否则false
index 检测 str 是否包含在列表中,如果是返回开始的索引值,否则返回-1
count 返回 str在start和end之间 在 mystr里面出现的次数
del 根据下标进行删除
pop 删除最后一个元素
remove 根据元素的值进行删除
sort 将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。
reverse 将list逆置
  • 列表的嵌套 schoolNames = [['北京大学','清华大学'], ['南开大学','天津大学','天津师范大学'], ['山东大学','中国海洋大学']]
  • 元组,Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。aTuple = ('et',77,99.9)
  • 字典info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}print(info['name'])info.get('age', 18)
  • 字典常用操作
方法/方式 说明
使用 变量名['键'] = 数据 这个“键”在字典中,不存在,那么就会新增这个元素,否则就是修改
del del info['name'] 删除一个元素 del info 删除整个字典
clear() 清空 info.clear()
len() 测量字典中,键值对的个数
keys 返回一个包含字典所有KEY的列表
values 返回一个包含字典所有value的列表
items 返回一个包含所有(键,值)元祖的列表
dict.has_key(key) 如果key在字典中,返回True,否则返回False
for key,value in dict.items() 遍历字典的key-value(键值对)
  • 如何实现带下标索引的遍历 --enumerate()

    >>> chars = ['a', 'b', 'c', 'd']
    >>> for i, chr in enumerate(chars):
    ...     print i, chr
    ...
    0 a
    1 b
    2 c
    3 d
    

列表表达式快速生成列表

a = [ x for x in rang(4)]
a
Out[4]: [0, 1, 2, 3]
b = [x for x in range(3, 10) if x%2!=0]
b
Out[6]: [3, 5, 7, 9]
c = [(x, y, z) for x in range(1,3) for y in range(3) for z in range(4,6)]
c
Out[8]: 
[(1, 0, 4),
 (1, 0, 5),
 (1, 1, 4),
 (1, 1, 5),
 (1, 2, 4),
 (1, 2, 5),
 (2, 0, 4),
 (2, 0, 5),
 (2, 1, 4),
 (2, 1, 5),
 (2, 2, 4),
 (2, 2, 5)]

set、list、tuple方法与转换

eg:

a = set()
type(a)
Out[3]: set
b = list()
type(b)
Out[5]: list
c = tuple()
type(c)
Out[8]: tuple
a = {1,2,3}
b = [1,2,2,2,2,4]
c = (1,2,3,4)
a
Out[12]: {1, 2, 3}
b
Out[13]: [1, 2, 2, 2, 2, 4]
c
Out[14]: (1, 2, 3, 4)
d = list(c) # tuple -> list
d
Out[16]: [1, 2, 3, 4]
e = set(b) #list->set 有去重的效果
e
Out[18]: {1, 2, 4}

公共方法

运算符

运算符 Python 表达式 结果 描述 支持的数据类型
+ [1, 2] + [3, 4] [1, 2, 3, 4] 合并 字符串、列表、元组
* 'Hi!' * 4 ['Hi!', 'Hi!', 'Hi!', 'Hi!'] 复制 字符串、列表、元组
in 3 in (1, 2, 3) True 元素是否存在 字符串、列表、元组、字典
not in 4 not in (1, 2, 3) True 元素是否不存在 字符串、列表、元组、字典 注意,in在对字典操作时,判断的是字典的键

python内置函数

Python包含了以下内置函数

序号 方法 描述
1 cmp(item1, item2) 比较两个值
2 len(item) 计算容器中元素个数
3 max(item) 返回容器中元素最大值
4 min(item) 返回容器中元素最小值
5 del(item) 删除变量

cmp

注意:cmp在比较字典数据时,先比较键,再比较值。

del

del有两种用法,一种是del加空格,另一种是del()

多维列表/元组访问的示例

>>> tuple1 = [(2,3),(4,5)]
>>> tuple1[0]
(2, 3)
>>> tuple1[0][0]
2
>>> tuple1[0][2]

引用

rentianxin@rentianxin-Desk /m/r/s/h/v/huaqin> ipython                                   

In [1]: a = 100

In [2]: b = a

In [3]: id(a)
Out[3]: 12146592

In [4]: id(b)
Out[4]: 12146592

In [5]: A = [11,22,33]

In [6]: B = A

In [7]: id(A)
Out[7]: 140151283711584

In [8]: id(B)
Out[8]: 140151283711584

In [9]: A.append(44)

In [10]: A
Out[10]: [11, 22, 33, 44]

In [11]: B
Out[11]: [11, 22, 33, 44]

在python中,值是靠引用来传递来的。只要出现=那一定是引用赋值。对于空引用的内存空间,会被垃圾回收器回收。

可以用is()判断两个引用所指的对象是否相同

可以用id()来获取变量的引用地址。 我们可以将id值理解为那块内存的地址标示。

可变类型与不可变类型

可变类型/引用类型 ,定义了之后值可以改变:

  • 列表 list
  • 字典 dict

不可变类型/值类型,定义了之后值就不可以再改变了:

  • 数值类型 int, long, bool, float
  • 字符串 str --字符串定义后,里面的字符就不可以单独更改了
  • 元组 tuple

函数

  • 在函数外边定义的变量叫做全局变量

  • 全局变量能够在所有的函数中进行访问

  • 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错

    a = 1
    def f():
        global a#不加这句话就会报错
        a += 1
        print a
    
  • 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的

  • 函数多返回值 sh, yu = divid(5, 2), 本质是使用元组

缺省参数

def printinfo( name, age = 35 ):

注意:带有默认值的参数一定要位于参数列表的最后面

不定长参数

基本语法如下:

    def functionname([formal_args,] *args, **kwargs):
       "函数_文档字符串"
       function_suite
       return [expression]
#例如:
def fun(a, b, *args, **kwargs):
    """可变参数演示示例"""
    print "a =", a
    print "b =", b
    print "args =", args
    print "kwargs: "
    for key, value in kwargs.items():
        print key, "=", value
#结果如下
#args = (3, 4, 5)
#kwargs: 
#p = 8
#m = 6
#n = 7

#例如
c = (3, 4, 5)
d = {"m":6, "n":7, "p":8}
fun(1, 2, *c, **d)    # 注意元组与字典的传参方式

加了星号()的变量args会存放所有未命名的变量参数,args为元组;而加*的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。

都是引用传参

Python中函数参数是引用传递(注意不是值传递)。对于不可变类型,因变量不能修改,所以运算不会影响到变量自身;而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量。

>>> a_int = 1 #定义了全局变量,假设地址为#0001
>>> def selfAdd(a):# 第一次调用a-> #0001  # 第二次调用a->#0008
...     """自增"""
...     a += a  #a 是不可变类型,不能修改,所以1+1 = 2 ,假设地址为 #0004,所以a -> #0004
        # a 是可变类型,+=是直接对#0008的控件进行修改,由[1,2] 变成[1, 2, 1, 2] ,所以a ->#0006,但是#0006这片空间的内容被改变了
...
>>> a_int#0001的值
1
>>> selfAdd(a_int)
>>> a_int#0001的值
1
>>> a_list = [1, 2] #假设地址为#0006
>>> a_list #0006的值
[1, 2]
>>> selfAdd(a_list) #传入#0006
>>> a_list #0006的值
[1, 2, 1, 2]
>>> a_int = 1 #定义了全局变量,假设地址为#0001
>>> def selfAdd(a):# 第一次调用a-> #0001  # 第二次调用a->#0006
...     """自增"""
...     a = a + a   # 我们更改了函数体的这句话
#第一次调用 a 是不可变类型,不能修改,所以1+1 = 2 ,假设数值2所在的地址为 #0004,所以a -> #0004
# a 是可变类型,先执行a + a,由[1,2] 变成[1, 2, 1, 2] ,假设地址为#0008,所以a ->#0008
...
>>> a_int#0001的值
1
>>> selfAdd(a_int)
>>> a_int#0001的值
1
>>> a_list = [1, 2]#假设地址为#0006
>>> a_list ##0006的值
[1, 2]
>>> selfAdd(a_list)
>>> a_list##0006的值
[1, 2]    

理解:

  1. python中对方法参数的赋值都是引用赋值

  2. a+=a =/= a= a + a 不完全相等

    注意和java中的值传递和引用传递做区别参考值传递与引用传递

匿名函数

用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。

lambda函数的语法只包含一个语句,如下:

    lambda [arg1 [,arg2,.....argn]]:expression

如下实例:

    sum = lambda arg1, arg2: arg1 + arg2

    #调用sum函数
    print "Value of total : ", sum( 10, 20 )

应用场合

函数作为参数传递

>>> def fun(a, b, opt):
...     print "a =", a
...     print "b =", b
...     print "result =", opt(a, b)
...
>>> fun(1, 2, lambda x,y:x+y)
a = 1
b = 2
result = 3

作为内置函数的参数

例如列表的排序参数

stus.sort(key = lambda x:x['age'])

注意事项:

  1. 函数名不能重复,因为没有重载函数的说法,不同参数的函数可以用缺省参数实现
  2. 调用时,实参的个数和先后顺序应该和定义函数中要求的一致
  3. 注意变量作用域

文件操作

open(文件名,访问模式)

 # 新建一个文件,文件名为:test.txt
    f = open('test.txt', 'w')
    f.write('hello world, i am here!')

    # 关闭这个文件
    f.close()

文件的读写

  1. 使用write()可以完成向文件写入数据,如果文件不存在那么创建,如果存在那么就先清空,然后写入数据(具体看访问模式)
  2. 使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
  • 如果open是打开一个文件,那么可以不用写打开的模式,即只写 open('test.txt')
  • 如果使用读了多次,那么后面读取的数据是从上次读完后的位置开始的
方法 描述 使用 注意
write() 向文件写入数据 f.write('hello world, i am here!') 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
read(num) 从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据 content = f.read(5) 如果使用读了多次,那么后面读取的数据是从上次读完后的位置开始的
readlines readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素 content = f.readlines() print(type(content)) i=1 for temp in content: print("%d:%s"%(i, temp)) i+=1

获取当前读写的位置

方法 描述 使用
tell() 在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取 # 查找当前位置 position = f.tell() print "当前文件位置 : ", position
seek(offset, from) 如果在读写文件的过程中,需要从另外一个位置进行操作的话,可以使用seek() seek(offset, from)有2个参数 offset:偏移量 from:方向 0:表示文件开头 1:表示当前位置 2:表示文件末尾 # 重新设置位置,从文件开头,偏移5个字节 f.seek(5,0)

文件的重命名、删除

方法 描述 使用
rename(需要修改的文件名, 新的文件名) os模块中的rename()可以完成对文件的重命名操作 import os os.rename("毕业论文.txt", "毕业论文-最终版.txt")
remove(待删除的文件名) os模块中的remove()可以完成对文件的删除操作 import os os.remove("毕业论文.txt")

文件夹的相关操作

方法 描述 使用
mkdir 创建文件夹 import os os.mkdir("张三")
getcwd() 获取当前目录 import os os.getcwd()
chdir() 改变默认目录 import os os.chdir("../")
listdir 获取当前文件夹下所有文件(包括文件夹)的名称 import os os.listdir("./")
rmdir 删除文件夹 import os os.rmdir("张三")
os.walk(top, topdown=True, onerror=None, followlinks=False) 文件遍历 dirpath 是一个string,代表目录的路径, dirnames 是一个list,包含了dirpath下所有子目录的名字。 filenames 是一个list,包含了非目录文件的名字。 这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name). for root, dirs, files in os.walk(file_dir): print(root) #当前目录路径 print(dirs) #当前路径下所有子目录 print(files) #当前路径下所有非目录子文件

面向对象

class Car:

    def __init__(self):#在创建对象后,就立刻被默认调用了
        self.wheelNum = 4
        self.color = '蓝色'
    #def __init__(self,name):
    #    self.name = name
    #    self.xue = 100
    #   self.qiang = None

    def move(self):
        print('车在跑,目标:夏威夷')
        
    def printName(self):
        print('名字为:%s'%self.name)
        
    #def anzidan(self,danjia,zidan):
    #    danjia.baocunzidan(zidan)

# 创建对象
BMW = Car()

print('车的颜色为:%s'%BMW.color)
print('车轮胎数量为:%d'%BMW.wheelNum)

“魔法”方法

def __str__(self): #相当于java的toString()方法
        msg = "嘿。。。我的颜色是" + self.color + "我有" + int(self.wheelNum) + "个轮胎..."
        return msg

#__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
def __new__(cls):
        print("这是 new 方法")
        return object.__new__(cls)

def __init__(self):
        print("这是 init 方法")

#构造方法
def __init__(self):#在创建对象后,就立刻被默认调用了
        self.wheelNum = 4
        self.color = '蓝色'

# 析构方法
# 当对象被删除时,会自动被调用
# 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
#当使用del删除变量指向的对象时,如果对象的引用计数不是1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除
def __del__(self):
   print("__del__方法被调用")
   print("%s对象马上被干掉了..."%self.__name)

__new__和__init__的作用

  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
  • __init__有一个参数self,就是这个__new__返回的实例,__init____new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
  • 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节

私有属性

def __init__(self, name):
    self.__name = name
  • Python中没有像C++中public和private这些关键字来区别公有属性和私有属性
  • 它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。

继承

class C(A,B):# class C 继承子A和B,私有的属性、方法,不会被子类继承,也不能被访问
#coding=utf-8
class Cat(object):
    def sayHello(self):
        print("halou-----1")
        
    def __init__(self,name):
        self.name = name
        self.color = 'yellow'



class Bosi(Cat):
    #重写父类的构造方法
    def __init__(self,name):
        # 调用父类的__init__方法1(python2)
        #Cat.__init__(self,name)
        # 调用父类的__init__方法2
        #super(Bosi,self).__init__(name)
        # 调用父类的__init__方法3
        super().__init__(name)

    
    #重写父类方法
    def sayHello(self):
        print("halou-----2")

bosi = Bosi()

bosi.sayHello()

多态

多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态

  • Python伪代码实现Java或C#的多态
class F1(object):
    def show(self):
        print 'F1.show'

class S1(F1):
    def show(self):
        print 'S1.show'

class S2(F1):
    def show(self):
        print 'S2.show'

# 由于在Java或C#中定义函数参数时,必须指定参数的类型
# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类
# 而实际传入的参数是:S1对象和S2对象

def Func(F1 obj):
    """Func函数需要接收一个F1类型或者F1子类的类型"""

    print obj.show()

s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show

s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
  • Python “鸭子类型”
class F1(object):
    def show(self):
        print 'F1.show'

class S1(F1):

    def show(self):
        print 'S1.show'

class S2(F1):

    def show(self):
        print 'S2.show'

def Func(obj):
    print obj.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj)

类属性、实例属性

class People(object):
    name = 'Tom'  #公有的类属性
    __age = 12     #私有的类属性
p = People()

print(p.name)           #正确
print(People.name)      #正确
print(p.__age)            #错误,不能在类外通过实例对象访问私有的类属性
print(People.__age)        #错误,不能在类外通过类对象访问私有的类属性

类属性就是类对象所拥有的属性,它被所有类对象实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象实例对象访问。

如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。

静态方法和类方法

1. 类方法

是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,能够通过实例对象和类对象去访问。

类方法可以获取类属性也可以对类属性进行修改:

class People(object):
    country = 'china'

    #类方法,用classmethod来进行修饰
    @classmethod
    def getCountry(cls):
        return cls.country

    @classmethod
    def setCountry(cls,country):
        cls.country = country


p = People()
print p.getCountry()    #可以用过实例对象引用
print People.getCountry()    #可以通过类对象引用

p.setCountry('japan')   

print p.getCountry()   
print People.getCountry()

2. 静态方法

需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

class People(object):
    country = 'china'

    @staticmethod
    #静态方法
    def getCountry():
        return People.country


print People.getCountry()

从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用

单例模式

# 实例化一个单例
class Singleton(object):
    __instance = None

    def __new__(cls, age, name):
        #如果类数字能够__instance没有或者没有赋值
        #那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时
        #能够知道之前已经创建过对象了,这样就保证了只有1个对象
        if not cls.__instance: #如果对象不存在
            cls.__instance = object.__new__(cls)
        return cls.__instance


# 实例化一个单例
class Singleton(object):
    __instance = None
    __first_init = False

    def __new__(cls, age, name):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, age, name):
        if not self.__first_init: # 如果是第一次加载,则执行一次__init__
            self.age = age
            self.name = name
            Singleton.__first_init = True

异常

#coding=utf-8
try:
    open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
    print('-----test--2---')
    print(num)# 如果num变量没有定义,那么会产生 NameError 异常

except (IOError,NameError): 
    #如果想通过一次except捕获到多个异常可以用一个元组的方式

    # errorMsg里会保存捕获到的错误信息
    print(errorMsg)

#coding=utf-8
try:
    num = 100
    print num
except NameError as errorMsg:
    print('产生错误了:%s'%errorMsg)
else:
    print('没有捕获到异常,真高兴')

#coding=utf-8  
import time
try:
    f = open('test.txt')
    try:
        while True:
            content = f.readline()
            if len(content) == 0:
                break
            time.sleep(2)
            print(content)
    except:
        #如果在读取文件的过程中,产生了异常,那么就会捕获到
        #比如 按下了 ctrl+c
        pass
    finally:
        f.close()
        print('关闭文件')
except:
    print("没有这个文件") 

异常的传递同java

抛出自定义异常

class ShortInputException(Exception):
    '''自定义的异常类'''
    def __init__(self, length, atleast):
        #super().__init__()
        self.length = length
        self.atleast = atleast

def main():
    try:
        s = input('请输入 --> ')
        if len(s) < 3:
            # raise引发一个你定义的异常
            raise ShortInputException(len(s), 3)
    except ShortInputException as result:#x这个变量被绑定到了错误的实例
        print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast))
    else:
        print('没有异常发生.')

main()

模块

在Python中有一个概念叫做模块(module),这个和Java中的包很类似,模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块

import模块

#1
import module1,mudule2... #在调用模块中的函数时,必须这样引用:模块名.函数名
#2
from 模块名 import 函数名1,函数名2.... #通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。
#3
from 模块名 import * #把一个模块的所有内容全都导入到当前的命名空间
#4
import time as tt #给time模块命名为tt,time这个名字不能再使用了
    

定位模块

当你导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
  4. 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

模块制作

每个Python文件都可以作为一个模块,模块的名字就是文件的名字。

例如

#test.py
    def add(a,b):
        return a+b

    # 用来进行测试
    ret = add(12,22)
    print('int test.py file,,,,12+22=%d'%ret)
#main.py
    import test #但是这样会有很大的问题,因为要先加载test模块,这个时候会先执行test模块中的类方法,也就是如上的测试代码,    即ret = add(12,22) print('int test.py file,,,,12+22=%d'%ret),而这些是根本不应该执行的,为此引入了__name__机制

    result = test.add(11,22) 
    print(result)

改进

#test.py
   # coding=utf-8

def add(a, b):
    return a + b


print(__name__)
# 用来进行测试,只有执行python test.py的时候该方法才能执行,因为只有这个时候__name__才等于__main__
if __name__ == '__main__':
    ret = add(12, 22)
    print('int test.py file,,,,12+22=%d' % ret)
#main.py
 import test # 在执行的时候,此时test.py 中的__name__变量等于`test`

result = test.add(3, 4)
print(result)

all变量

如果一个文件中有all变量,那么也就意味着这个变量中的元素,不会被from xxx import *时导入

__all__ = ['add', 'test1']


def add(a, b):
    return a + b


def test1():
    print('test1')


def test2():
    print('test2')

将文件夹配置成模块

在文件夹下创建__init__.py文件

在文件夹下面写入要导入的文件(.py)的文件名

例如

__all__ = ['test', 'msg']
  • 包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为
  • 有效避免模块名称冲突问题,让应用组织结构更加清晰
  • __init__.py 控制着包的导入行为
  • __init__.py文件中,定义一个__all__变量,它控制着 from 包名 import *时导入的模块
  • 可以通过import Phone.Mobile.Analog的方式导包

模块发布

新建setup.py配置文件

from distutils.core import setup #导入发布工具包

setup(name="dongGe", version="1.0", description="dongGe's module", author="dongGe", py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd'])

mymodule目录结构体如下:

.
├── setup.py
├── suba
│   ├── aa.py
│   ├── bb.py
│   └── __init__.py
└── subb
    ├── cc.py
    ├── dd.py
    └── __init__.py

构建模块

python setup.py build -- 会生成一个build目录

生成发布压缩包

python setup.py sdist 打包后,生成最终发布压缩包dongGe-1.0.tar.gz

模块安装、使用

1.安装的方式

  1. 找到模块的压缩包
  2. 解压
  3. 进入文件夹
  4. 执行命令python setup.py install

注意:

  • 如果在install的时候,执行目录安装,可以使用python setup.py install --prefix=安装路径

2.模块的引入

在程序中,使用from import 即可完成对安装的模块使用

from 模块名 import 模块名或者*

脚本技巧

传参:

import sys

print(sys.argv)

#rentianxin@rentianxin-Desk ~/D/P/HelloWord> python3 params.py a b 1
#['params.py', 'a', 'b', '1']

你可能感兴趣的:(python 基础总结)