Python 基础语法

本文全面介绍了Python编程的基础知识,包括变量定义、数据类型转换、流程控制、函数定义与调用、文件操作等内容,适合初学者快速入门。

注释

  • 单行注释用 #
  • 多行注释用 '''xxx'''

打印print

# 定义变量
a = 100
# 输出a的类型
print(type(a))
# 格式化输出a
print("a=%d"%a)
print("a=%x"%a) #16进制
# 输出字符串
b="xiaobai"
print("name=%s"%b)

#换行输出
print("hello world \n good morning")    

#输出多个参数
a = 1
b = "str"
c = 3.12
print("a = %d b = %s c = %.2f"%(a, b, c))

#输出数据后不换行
i = 1
while i <= 5:
    j = 1
    while i >= j:
        print("* ", end="")
        j += 1

    i += 1
    print("\n")
    pass

输出: 
* 
* * 
* * * 
* * * * 
* * * * * 

输入input

python2:raw_input()
python3:input()

//将输入的文字保存到name
name = input("请输入名字")
print("你的名字%s"%name)

//通过input输入的数据是以字符串的形式存在的,如果需要计算,需要转成对应的类型
userName = input("请输入用户名")
print(userName)
age = input("请输入年龄")
age = int(age) + 1
print(age)
运算符

//:取整除,去掉小数部分

print(10//3)

a = 10
a += 10//3
print(a)

类型转换

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 ) 将一个整数转换为一个八进制字符串

if else

  • python的if和else语句后要跟":",pass是占位符,不执行任何操作。
  • if 和 else 代码块内如果要执行多条语句,这多条语句前都要有TAB的空格,即都要缩进相同的程度;
a = 1
if a > 10:
    print("a > 10")
else:
    print("a < 10")
    print("a < 10")
    print("a < 10")
    pass

print("end")

while

while a < 10:
    print(a)
    a += 1
    pass

for

for i in range(1,10):
    print(i)
    pass

for i in "xiaobai":
    print(i)
    pass

字符串

定义字符串使用单引号或双引号都可以
str = 'xiaobai'
str = "xiaobai"
下标,通过下标访问字符串中的字符
print(str[0])
print(str[1])
字符串拼接
//使用 + 号
a = "xiao"
b = "bai"
print(a+b)  //xiaobai

c = "%s%s"%(a,b)

//使用格式字符串
c = "%s%s"%(a,b)
print(c)

d = "%s"%(a+b)
print(d)
字符串长度
a = "xiaobai"
len(a)
切片

截取对象一部分数据,语法:[起始:结束:步长] 选取的区间属于左闭右开型,即从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身)。

str = "xiaobai"
print(str[2:5]) //输出aob,从下标2开始,截取到下标5的前一位,也就是下标4
print(str[2:]) //下标2开始,直到字符串结束

print(str[1:-2]) //下标1开始,到最后第3个之间的字符

print(str[:3])  //下标0开始,到下标3之前的字符

print(str[::3]) //步长为3,从下标0开始,截取 0 3 6 9...,直到字符串结束,

print(str[1:6:2]) //从下标1开始,到下标5结束,步长为2
字符串逆序
a = "xiaobai"
print(a[-1::-1]) //从最后一个元素开始,步长为-1,

print(a[::-1])  //从下标0开始,直到字符串结束,步长为-1,系统会自动颠倒起始位置和结束位置
find 字符串查找

如果字符串存在,返回首字符下标,否则返回-1

a = "xiaobai"
a.find("a") //返回2

a.rfind("a")    //从右向左查找

index:功能和find相同,如果查找失败,会返回系统错误

count 查找的字符串出现的个数
a = "xiaobai"
print(a.count("a")) //2,查找字符“a” 在字符串中出现的次数
replace 替换
a = "xiaobai"

print(a.replace("a", "xxx"))    //替换字符串中所有的"a"字符
print(a.replace("a", "xxx", 1)) //替换字符串中的第一个“a”字符
split 分割字符串
a = "xiao bai"
print(a.split(" ")) //['xiao', 'bai'],通过空格分割字符串
capitalize 首字母大写
a = "xiao bai"
print(a.capitalize())
title 每个单词首字母大写
a = "xiao bai"
print(a.title())
startsWith/endswith
a = "xiao bai"

print(a.startswith("xi"))
print(a.endswith("ai"))
lower upper 全部字符大小写
a = "xiao bai"

print(a.upper())
print(a.lower())
左对齐、右对齐、居中
a = "xiao bai"

//返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
print(a.ljust(20))

//返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
print(a.rjust(20))

//返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
print(a.center(20))
删除空白字符
a = "    xiao bai    "

# //删除左边空格
print(a.lstrip())  

# 删除右边空格
print(a.rstrip())

# 删除两边空格
print(a.strip())
分割字符串 partition rpartition
//从左到右,以字符串“new"为界,将字符串a分割成3部分
a = "happy new year"
print(a.partition("new")) //('happy ', 'new', ' year')

//从右到左
print(a.rpartition("new")) //('happy ', 'new', ' year')
分割字符串 splitlines
a = "happy\n new\n year"
//按照行分隔,返回一个包含各行作为元素的列表
print(a.splitlines())
isalpha 检查是否全是字母
a = "xiaobai1"
print(a.isalpha()) //False

b = "xiaobai"   //True
print(b.isalpha())
isdigit 检查是否全是数字
a = "1234"
print(a.isdigit()) //True

a = "1234a"
print(a.isdigit()) //False
isalnum 检查是否是字母或数字
a = "1234"
print(a.isalnum())  //True

a = "123 4a"
print(a.isalnum()) //False 有空格
isspace 检查是否是空格
a = "12 34"
print(a.isspace()) //false

a = "   "
print(a.isspace()) true
join 合并字符串
str = "_"
arr = ["aaa", "bbb", "ccc"]
//arr 中每个字符后面插入str,构造出一个新的字符串
print(str.join(arr)) //aaa_bbb_ccc

 

列表

Python的列表就是数组,与其他语言不同的是,Python列表可以存不同类型的数据。

定义
arr = [1, 1.23, "xiaobai"]
print(arr)  #[1, 1.23, 'xiaobai']

print(arr[0])
print(arr[1])

//遍历列表
for item in arr:
    print(item)
添加元素

append 列表末尾追加元素

arr = [1, 1.23, "xiaobai"]
arr.append("xiaohei")
print(arr)

extend 将一个列表的元素添加到另外一个列表中

a = [1, 2, 3]
b = ["a", "b", "c"]
a.extend(b)
print(a)

insert 在指定位置插入元素

a = [1, 2, 3]
//在位置1添加元素xiaobai
a.insert(1, "xiaobai")
print(a)
修改元素
a = [1, 2, 3]
a[1] = "xiaobai"
print(a) //[1, "xiaobai", 3]
查找元素

in notin

a = [1, 2, 3]

print("xiaobai" in a)   //False
print("xiaobai" not in a)   //True

index

a = [1, 2, 3, 1, 2, 3]

print(a.index(3)) //查找元素3在列表a中的位置
print(a.index(3, 3, 6)) //在列表a中,从第3个元素开始,第6个元素结束,查找元素3

count

a = [1, 2, 3, 1, 2, 3]

print(a.count(1))   //元素1出现的次数
print(len(a))   //字符串长度
删除元素
a = [1, 2, 3, 1, 2, 3]

del a[2]        #删除第二个元素
print(a)

a.pop()     #删除最后一个元素
print(a)

a.remove(1)     #删除指定元素
print(a)
排序(sort, reverse)
a = [1, 2, 3, 1, 2, 3]

a.reverse() #逆序 [3, 2, 1, 3, 2, 1]
print(a)

a.sort()
print(a) #从小到大排列 [1, 1, 2, 2, 3, 3]

a.sort(reverse = True) #从大到小 [3, 3, 2, 2, 1, 1]
print(a)

字典

定义字典
info = {"name":"xiaobai", "age":20, "address":"beijing"}
print(info)

print(info["name"])
print(info["age"])

height = info.get("height") #通过get方法从字典取值,如果对应的值不存在,会返回NONE
print(height)

height = info.get("height", 175) ##通过get方法从字典取值,可以设置默认值,如果对应的值不存在,会返回设置的默认值
print(height)

height = info["height"]
print(height)  # info中不存在 height键,会报错
元素操作
info = {"name":"xiaobai", "age":20}

info["name"] = "xiaohei"    #修改元素的值
print(info["name"])

info["address"] = "beijing" #添加元素
print(info)

del info["name"]    #删除元素
print(info)

del info    #删除字典
print(info)

info.clear()    #清空字典
print(info)
其他操作
info = {"name":"xiaobai", "age":20}

print(len(info))    #字典长度

print(info.keys())  #获取字典的所有键

print(info.values()) #获取字典所有值

print(info.items()) #获取所有键值的元组

# print(info.has_key("name"))   #Python3删除了这个方法

if "name" in info:
    print(info["name"])
遍历字典
info = {"name":"xiaobai", "age":"20"}
for (key, value) in info.items():
    print("%s %s"%(key, value))
//name xiaobai
//age 20

for item in info.items():
    print(item)
//('name', 'xiaobai')
//('age', '20')

元组

Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。index和count与字符串和列表中的用法相同

_tuple = ("xiaobai", 20)
print(_tuple[0])
print(_tuple[1])

print(len(_tuple))

print(_tuple.index(20))

公共方法

运算符
+   合并  字符串、列表、元组
*   复制  字符串、列表、元组
in  元素是否存在  字符串、列表、元组、字典
not in  元素是否不存在 字符串、列表、元组、字典
内置函数
len(item)   计算容器中元素个数
max(item)   返回容器中元素最大值
min(item)   返回容器中元素最小值
del(item)   删除变量
id(item)    输出item的内存地址

函数

函数定义
# 不带参数不带返回值
def test():
    print("xiaobai")
    print("ni hao")

test()

# 带参数 没有返回值
def test1(a, b):
    print("a=%d, b=%d"%(a, b))

test1(1, 2)

# 不带参数,有返回值
def test2():
    return 20

print(test2())

# 带参数 带返回值
def test4(name, age):
    info = ("name = %s, age = %d"%(name, age))
    return info

print(test4("xiaobai", 20))
infp = test4(age = 20, name = "xiaobai")
infp = test4(name = "xiaobai", age = 20)
全局变量
  • 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
  • 对于可变类型的全局变量,比如列表、字典,在函数内修改时可以不用加global
c = 100 //定义全局变量c
def test():
    a = 10
    b = 20
    print(a + b)
    global c    //引用全局变量C
    c = 30  //修改全局变量

test()
print(c)

//可变类型全局变量
arr = [1, 2]

def test():
    arr.append(3)

test()
print(arr)
元组作为返回值
def test():
    return(1, "xiaobai")

a ,b = test()
print("a=%d, b=%s"%(a, b))
默认参数
  • 默认参数必须放在参数列表的最后
def test(name, age=30):     //age有默认参数30
    print("name=%s, age=%d"%(name, age))

//只传入name,age取默认值
test("xiaobai") //name=xiaobai, age=30
test("xiaobai", 20) //name=xiaobai, age=20
可变参数
  • 以 “*” 开头的形参,用来存放所有未命名的参数,args是元组;
  • 以 “**” 开头的形参,用来存放命名参数,kwargs是字典
  • args、kwargs只是形参名,可以任意改变
def test(a, b, *args, **kwargs):
    print("a=%d, b=%d"%(a, b))
    print(args)
    print(kwargs)

test(1, 2, 3, 4, k = 5, w = 6)

输出:
a=1, b=2
(3, 4)
{'k': 5, 'w': 6}
拆包
def test(a, b, *c, **d):
    print("a=%d, b=%d"%(a, b))
    print(c)
    print(d)

test(1, 2, (3, 4), {"k":5, "w":6})

输出:
a=1, b=2
((3, 4), {'k': 5, 'w': 6})
{}

元组和字典被当做一个参数,传递给了未命名的变量,如果需要将元组和字典的值取出来,分别传递给未命名参数和命名参数,需要将元组和字典进行解包。

def test(a, b, *c, **d):
    print("a=%d, b=%d"%(a, b))
    print(c)
    print(d)

test(1, 2, *(3, 4), **{"k":5, "w":6})

输出
a=1, b=2
(3, 4)
{'k': 5, 'w': 6}

“*”、“**”如果放在参数前面,表示解包;
可变类型、不可变类型
  • 可变类型:列表、字典
  • 不可变类型:数字、字符串、元组
a = 100     //定义数字a,值为100,其实质是内存分配空间存储数值100,然后将内存地址赋给变量a,变量a只存的是内存地址

b = a       //b 和 a指向相同的内存地址
 
a = 200     //变量a指向存放200的内存地址
id(a)       //查看a指向的内存地址
引用传参
  • Python中函数参数都是引用传递
def test(a):
    a = a + 10

a = 10
test(a)
print(a)
//因为变量a是数值类型,是不可变类型,所以调用参数不会影响变量本身;

def test(a):
    a.append(3)

a = [1, 2]
test(a)
print(a)
//列表是可变类型,函数调用会影响变量本身;
匿名函数
  • 匿名函数使用lambda声明
  • 匿名函数可以接收任意数量的参数,但是只能返回一个表达式的值
sum = lambda a, b: a + b
print(sum(1, 2))    //3

//匿名函数做参数
def test(a, b, opt):
    return opt(a, b)
print(1, 2, lambda a, b: a + b)

使用匿名函数为列表排序

stus = [
    {"name":"zhangsan", "age":18}, 
    {"name":"lisi", "age":19}, 
    {"name":"wangwu", "age":17}
]

//按照“name”先后顺序重新排序列表
stus.sort(key = lambda x: x["name"])
print(stus)

从终端输入函数作为参数

def test(a, b, func):
    return func(a, b)

func_new = input("请输入函数")   //让用户输入匿名函数
func_new = eval(func_new)   //Python3 去掉字符串的引号,使输入的数据成为函数

num = test(11, 22, func_new)

print(num)
交换数据

python中都是地址引用,直接交换两个变量即可

a = 4
b = 5
c = a
a = b
b = c

//使用元组
(a, b) = (b ,a)
a, b = b, a

 

文件操作

打开、关闭文件
f = open("text.txt", "a+")
print(f)

f.close()
文件读写模式
  • r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
  • w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
  • rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
  • wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
  • r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
  • w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
  • rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
  • wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
写数据
f = open("test.txt", "w")
f.write("hello world")
读数据 read
  • read(num) :读取指定长度的数据
  • read(): 读取所有数据
  • 执行一次读取数据操作后,文件指针会移动到对应长度数据后边,再执行一次读数据操作,会从上次读取的位置继续读取;
f = open("test.txt")
content = f.read(5) #读取指定长度的数据
print(content)

content1 = f.read() //从位置5开始读取剩下的所有数据
print(content1)
读数据 readlines
  • readlines(): 一次性读完所有数据,返回的结果是列表,每一行数据是列表的一个元素;
f = open("test.txt")
content = f.readlines()
for item in content:
    print item
读数据 readline
  • readline:一次读取一行数据
f = open("test.txt")
content = f.readline()
print(content)

content = f.readline()
print(content)

content = f.readline()
print(content)
获取当前读写位置 tell()
f = open("test.txt")

content = f.read(3)
print(content)

pos = f.tell()
print(pos)  # 3

content = f.read(10)
print(content)

pos = f.tell()
print(pos)  #13
定位 seek()
  • 第一个参数:偏移的位置
  • 第二个参数:0:文件开头, 1:当前位置, 2:文件末尾
  • 在文本文件中,没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置,从文件尾计算时就会引发异常,打开文件模式需要设置为 rb+。
f = open("test.txt","rb+")

f.seek(3, 0)    #定位到 开头 3个字节
pos = f.tell()
print(pos)

f.seek(3, 2)
pos = f.tell()
print(pos)
文件夹操作
#导入 os 模块
import os

#切换目录
os.chdir("/Users/xxx/Desktop")

#获取当前目录下所有文件列表
dirlist = os.listdir()
print(dirlist)

#获取当前路径
pwd = os.getcwd()
print(pwd)

#创建文件夹
os.mkdir("xiaobai")

#删除文件夹
os.rmdir("xiaobai")

创建对象
  • 定义对象的方法时,第一个参数必须是self,代表调用方法的对象本身;
class Person:

    #__init__ 是初始化方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #打印输出对象时,会调用__str__方法
    def __str__(self):
        return "name = %s, age = %d"%(self.name, self.age)

    #定义方法,
    def run(self):
        print("run")

#创建对象
person = Person("xiaobai", 20)
print(person.name)
print(person.age)

#修改对象的属性
person.name = "xiaogei"

#新增对象属性
person.height = 180
print(person.height)

#调用对象方法
person.run()
隐藏数据

通过调用方法实现属性的读写的好处是可以对数据进行判断

class Person:

    def setage(self, age):
        if age < 0:
            self.age = 0
            return
        self.age = age

    def getage(self):
        return self.age

person = Person()

person.setage(10)
print(person.getage())

person.setage(-10)
print(person.getage())

通过方法读写属性虽然可以做到隐藏数据的功能,但是属性还是可以通过person.age获取到,要做到完全隐藏属性,需要将属性定义为私有属性.

class Person:

    def __init__(self, age):
        self.__age = age

    def setage(self, age):
        if age < 0:
            self.__age = 0
            return

        self.__age = age

    def getage(self):
        return self.__age


person = Person(20)

person.setage(10)
print(person.getage())

person.setage(-10)
print(person.getage())

此时通过 person.age 或 person.age 是无法访问到属性的。在Python中定义私有属性,需要在属性前面加“";

私有方法

定义私有方法,在方法前加"__"

class Person:

    def test1(self):
        print("test1")

    def __test2(self):  #私有方法
        print("test2")


person = Person()

person.test1()
person.test2()  //访问私有方法,报错
__ del __ 类析构方法

__ del __ 是在对象被删除的时候调用

class Person:

    def test1(self):
        print("test1")

    def __test2(self):
        print("test2")

    def __del__(self):
        print("del ---")

person = Person()
person.test1()
del person  #删除person对象,会调用__ del __方法
sys.getrefcount(T) 获取引用计数
import sys

class Person:

person = Person()

#获取对象引用个数,会比实际的个数多1
print(sys.getrefcount(person))
    
del person
#删除对象之后再获取引用计数会崩溃
print(sys.getrefcount(person))  
继承
class Cat(object):
    
    def __init__(self, name, color="白色"):
        self.name = name

    def run(self):
        print("%s 在跑"%self.name)

class Bosi(Cat):
    def setname(self, name):
        self.name = name

bosi = Bosi("xiaobai")

print(bosi.name)
bosi.run()
        

继承不能访问父类的私有属性和方法

class Cat(object):

    def __init__(self, name, color="白色"):
        self.__name = name

    def __run(self):
        print("%s is running"%self.__name)

    def eat(self):
        print("%s is eating"%self.__name)

    def getname(self):
        print(self.__name)

class Bosi(Cat):
    pass
        
        
bosi = Bosi("xiaobai")
print(self.__name)  #报错,不能访问父类的私有属性
bosi.getname()

bosi.__run()    #报错,不能访问父类的私有方法
多继承

python支持继承多个类

class A(object):
    def test(self):
        print("a print")

class B(object):
    def test(self):
        print("b print")

class C(B, A):
    pass    
        
c = C()
c.test()
print(C.__mro__)    #打印C类搜索方法时的先后顺序
重写父类方法
class Cat(object):
    def __init__(self, name):
        self.name = name

    def eat(self):
        print("cat eat fish")

class Bosi(Cat):

    def __init__(self, name):
        #调用父类的初始化方法
        super(Bosi, self).__init__(name)

    #重写父类方法
    def eat(self):
        print("bosi eat fish")
        
bosi = Bosi("bosi")
print(bosi.name)
bosi.eat()
        
多态
class Dog(object):
    def show(self):
        print("dog show self")  

class Xiaobai(Dog):
    def show(self):
        print("xiaobai show self")

class Xiaohei(Dog):
    def show(self):
        print("xiaohei show self")

xiaobai = Xiaobai()
xiaobai.show()      #xiaobai show self

xiaohei = Xiaohei()
xiaohei.show()      #xiaohei show self
类属性
  • 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,
  • 对于公有的类属性,在类外可以通过类对象和实例对象访问
  • 不能在类外通过类对象或实例对象访问私有的类属性
class People(object):
    name = "xiaobai"
    __age = 20

print(People.name)
print(People.__age)

xiaoming = People()
print(xiaoming.name)
print(xiaoming.__age)
修改类属性
  • 必须通过类对象在类外修改类属性。
  • 如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
class People(object):
    name = "xiaobai"

print(People.name)

people = People()
print(people.name)

#通过类对象修改类属性
People.name = "xiaohei"
print(People.name)  #xiaobai
print(people.name)  #xiaobai

# 通过实例对象修改类属性
people.name = "xiaohei"
print(people.name)      #xiaohei
print(People.name)      #xiaobai

del people.name
print(people.name)      #xiaobai
类方法
  • 类方法前面必须加 @classMethod修饰
  • 类方法的第一个参数必须是类对象,通常用cls作为第一个参数
  • 实例对象和类对象都可以访问类方法
class Person(object):
    
    name = "xiaobai"

    @classmethod
    def getname(cls):
        return cls.name

    @classmethod
    def setname(cls, name):
        cls.name = name

#通过类调用类方法
print(Person.getname()) #xiaobai
Person.setname("xiaohei")
print(Person.getname()) #xiaohei

#通过实例对象调用类方法
person = Person()
print(person.getname()) #xiaohei
person.setname("xiaobai")
print(person.getname()) #xiaobai
静态方法
  • 实例方法需要加 @staticmethod修饰
  • 实例方法不需要添加额外的参数
  • 实例方法中可以调用类属性及方法、实例属性及方法
class Person(object):
    
    name = "xiaobai"

    def setage(self, age):
        self.age = age

    @staticmethod
    def showinfo():
        print("*" * 10)
        print("hello world")
        print("*" * 10)

        #访问类属性
        print("name = %s"%Person.name)

        #调用实例
        person = Person()
        person.setage(20)
        print("age = %d"%person.age)

#通过类调用静态方法
Person.showinfo()

#通过实例对象调用静态方法
person = Person()
person.showinfo()
__new__方法
  • __new__方法是在创建对象实例时调用
  • __new__方法中必须调用父类的__new__方法方法
class Dog(object):
    def __init__(self):
        print("____init_____")

    def __del__(self):
        print("________del_______")

    #__new__方法的第一个参数是类对象
    def __new__(cls):
        print("______new________")
        #调用object的__new__方法
        return object.__new__(cls)

dog = Dog()

输出:
______new________
____init_____
________del_______
单例模式
class Dog(object):
    __instance = None

    def __new__(cls):
    
        #如果类的实例对象不存在,调用父类的new方法创建实例
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        
        return cls.__instance

dog = Dog()
print(id(dog))
dog1 = Dog()
print(id(dog1))

输出:
4321567912
4321567912
创建单例 只执行一次__init__方法
class Dog(object):
    __instance = None
    __First_init = False

    def __init__(self, name):
    
        #如果执行过__init__方法,不再执行
        if not self.__First_init:
            print("____-init_____")
            self.name = name
            Dog.__First_init = True

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


dog = Dog("xiaobai")
print(id(dog))
print(dog.name)
dog1 = Dog("xiaohei")
print(id(dog1))
print(dog1.name)

//因为只执行了一次init方法,所有第二次创建对象时返回的是上一次创建的对象
输出
____-init_____
4322616936
xiaobai
4322616936
xiaobai
捕获异常
try:
    print("rrrrrrrr")
    print(a)    #变量a没有定义,会产生NameError
    print("rrrrrrrr")

//捕获错误
except (NameError):
    print("errror")

捕获多个异常:多个异常使用元组表示

try:
    print("rrrrrrrr")
    open("", "w")
    print(a)
    print("rrrrrrrr")
except (FileNotFoundError, NameError):
    print("errror")
else:
    pass
finally:
    pass

获取异常的信息描述

try:
    print("rrrrrrrr")
    open("", "w")
    print(a)
    print("rrrrrrrr")

#将FileNotFoundError, NameError异常信息存储到 error中
except (FileNotFoundError, NameError) as error:
    print(error)
else:
    pass
finally:
    pass

捕获所有异常

try:
    print("rrrrrrrr")
    open("", "w")
    print(a)
    print("rrrrrrrr")
except Exception as errror:
    print(errror)
    
#如果没有捕获到异常,会执行else的语句
else:
    pass
    
#无论是否捕获到异常,都会执行的语句
finally:
    pass

自定义异常

  • 抛出自定义异常使用raise关键字,异常必须是Error或Exception的子类
class ShortInputException(Exception):
    
    def __init__(self, length, atleast):
        super(ShortInputException, self).__init__()
        self.length = length
        self.atleast = atleast

def main():
    try:
        content = input("请输入")
        if len(content) < 3:
            raise ShortInputException(len(content), 3)
    except ShortInputException as result:
        print("输出内容长度%d, 最少长度%d"%(len(content), 3))
    else:
        print("输入内容长度正确")
    finally:
        pass

main()

模块

import 模块
  • 调用模块内的方法必须加上模块名,因为有可能存在同名的函数
import math #导入math模块

#调用math模块内的sqrt方法
print(math.sqrt(4)) 
from ... import...
  • 从模块中导入指定的方法,调用模块的方法不需要加模块名
from math import sqrt
print(sqrt(4))
import * from...
  • 将模块中的内容全部导入当前命名空间
import ... as ...
  • 给导入的模块起别名
import math as tt
print(tt.sqrt(4))

#如果调用math.sqrt(4) 会报找不到方法的错误
print(math.sqrt(4))
自定义模块

//test.py, 自定义文件

def add():
    return 1 + 2

//1.py, 导入test.py,调用test.py中的add方法

import test
print(test.add())
__name__
  • __name__ 表示当前模块的名称,可以根据name变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码
def add():
    return 1 + 2

# 根据当前模块的名称,是否需要输出测试信息或日志
if (__name__ == "main"):
    print("test msg")
__all__
  • 模块中如果定义了__all__,那只有__all__中的方法或类可以被访问
  • 引入模块的文件必须使用 form ... import * 这种方式导入模块
//test.py

# 当其他文件导入test模块时,只能使用Test类 和 test1方法
__all__ = ["Test", "test1"]

class Test(object):
    def test(self):
        print("function test")

def test1():
    print("function test1")

def test2():
    print("function test2")
    

//main.py
#导入test模块
from test import *

a = Test()
a.test()
test1()
test2() #test模块不允许使用test2()方法,会报错

输出:
NameError: name 'test2' is not defined

包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为包

main.py 和 test.py都在Python目录下

//main.py
def sendmsg():
    print("send msg")
    
//test.py
def getmsg():
    print("get msg")
    
//1.py
#导入main 和 test模块,并调用其中的方法,需要给出模块完整的路径
import python.main
import python.test

python.main.sendmsg()
python.test.getmsg()

通过导入文件夹下所有文件的方式导入模块,只会导入文件夹,文件夹下的模块不会导入

from python import *

python.main.sendmsg()   #报错
python.test.getmsg()    #报错

解决办法:

  • 在模块文件夹下创建__init__.py文件,
  • 定义一个all变量,控制着 from 包名 import *时导入的模块
//main.py
def sendmsg():
    print("send msg")
    
//test.py
def getmsg():
    print("get msg")
    
//__init__.py
__all__ = ["main", "test"]

//1.py
from python1 import *
main.sendmsg()
test.getmsg()

列表推导式

a = [x for x in range(4)]
print(a)

输出:[0, 1, 2, 3]

等价于:
a = []
for x in range(4):
    a.append(x)
print(a)
过滤数值
//取0-29,可以被3整除的数
a = [x for x in range(30) if x % 3 is 0]
print(a)
使用函数
def double(x):
    return x * x
a = [double(x) for x in range(10) if x % 2 == 0]
print(a)

double(x):生成列表的函数
for x in range(10):迭代表达式
if x % 2 == 0: 过滤表达式
多个for循环
a = [(x, y) for x in range(3) for y in range(3, 5)]
print(a)
输出:[(0, 3), (0, 4), (1, 3), (1, 4), (2, 3), (2, 4)]

a = [(x, y, z) for x in range(3) for y in range(3, 5) for z in range(5, 8)]
print(a)
输出:
[(0, 3, 5), (0, 3, 6), (0, 3, 7), 
(0, 4, 5), (0, 4, 6), (0, 4, 7), 
(1, 3, 5), (1, 3, 6), (1, 3, 7), 
(1, 4, 5), (1, 4, 6), (1, 4, 7), 
(2, 3, 5), (2, 3, 6), (2, 3, 7), 
(2, 4, 5), (2, 4, 6), (2, 4, 7)]
//将列表a 分成3个子列表
a = [1, 2, 3, 4, 5, 6, 7, 8 ,9]
b = [a[x:x+3] for x in range(0, len(a), 3)]
print(b)

输出:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

dict

dic = {"xiaobai": 20, "xiaohei": 30, "xiaohong": 40}
print(dic["xiaobai"])

# 如果dic种不存在xiaohui,会返回get后面指定的数值
a = dic.get("xiaohui", 50)
print(a)

#删除对象
dic.pop("xiaobai")
print(dic)

set

  • set中没有重复的值
# 将列表转成set,set会自动过滤重复的值
a = [1, 2, 3, 4, 4, 3 ,2]
b = set(a)
print(b) #{1, 2, 3, 4} 

#添加删除元素
a.add(4) 
a.remove(4)

set list tuple转换

a = [1, 2, 3]
//列表转元组
b = tuple(a)
print(b)

//元组转set
c = set(b)
print(c)

//set转列表
d = list(c)
print(d)

__main__

//test.py
def test():
    print(__name__)

test()  
输出:__main__

//1.py
from test import *

test()
输出:test test

如果我们是直接执行某个.py文件的时候,该文件中那么”__name__ == '__main__'“是True,但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。

这个功能还有一个用处:调试代码的时候,在”if __name__ == '__main__'“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!

转载于:https://my.oschina.net/mexiaobai1315/blog/1622094

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值