一、基础语法
1.类型
1)整数、浮点数、复数,数据类型转换
id(num1) #内存地址
list1=[11,22]
list2=[11,22]
print(list1 == list2)
print(list1 is list2) #判断id是否相等,相应的有 is not
结果:
True
False
num1,num2 = 1.0,2 #交互式赋值,定义变量初始值
注意如果后面的赋值一样,则等同于链式赋值,即num1=num2 =某个数,num1,num2 的内存地址是一样的,但是如果其中一个变量改变了,其内存地址不变,而另外一个变量的值不会变,内存地址也是之前的地址。
c,d=20,20
print(c,d)
print(id(c))
print(id(d))
c=34
print(c,d)
print(id(c))
print(id(d))
结果:
20 20
1694199872
1694199872
34 20
1694200320
1694199872
数据类型转换和Java一致,例如int('123'),得到int类型的123,使用type(变量名)查看具体类型。
浮点数计算会有误差。
print(max(1,2,3,4)) #输出最大,min输出最小
print(round(3.1024,2)) #保存小数点后面几位
import math
print(math.ceil(18.2)) #向上取整
print(math.floor(12.3)) #向下取整
print(math.modf(12.3)) #返回小数和整数部分,都是浮点数形式
import random
print(random.choice([1,2,3,4])) #随机取出所给序列中的一个数,也可以数和字符混合放入序列中
print(random.randrange(1,100,2)) #指定的基数中,随机选取一个数,例如1-99,步进为2,即1,3,5,7,9......99,随机选出一个
list=[2,4,5,1] #以下,将list元素重新排列
random.shuffle(list)
print(list)
print(random.uniform(1,9)) #随机产生1-9之间的实数,包含1和9
2)运算符
+、-、*、/、//取整、%取模、**求幂、&与运算、|或运算、^异或运算、<<向左移动,>>向右移动
3)字符串
特殊字符串转义,r"\a\b",直接在字符串前加r即可
print("ss"*3) #复制3份
print("num = %d,str=%s"%(10,"hggg")) # %d这样的称为占位符
print( #更清楚地看到换行,而不需要用\n,当文本中含有多个需要转义的时候可以用''' '''
''' gg
jj ''' )
print(eval("12+3")) #当成一个有效的表达式求值
a = int(input()); #一个数的位数
print(len(str(a)))
print(a)
title()每个单词首字母大写,upper(),lower(),capitalize()句子首个单词的首字母大写
print(a.startswith('a'))、print(a.endswith('b')) 用来判断是否是以某个字符开始或结尾
print("dante".center(20,"*")) # 效果为*******dante********
print("dante".zfill(10)) #效果为00000dante
print("dante dante dante".count("te",0,29)) #统计字符串中某个字符串的个数,可以加两个参数,例如下标从0开始,到29结束
print("dante".find("h")) #返回"h"第一次出现的下标,从左向右,没有返回-1,rfind至右向左查找,和index()效果一样,只是index查找不到会报错
print(" dante".strip()) #将字符串两边的空格去掉,如果只去掉左边或者右边,用lstrip或者rstrip,strip括号内可以加一个指定的字符串,例如strip("*")去掉字符串两边的*
str.replace("g","d")#替换指定字符串
sys中intern方法强制2个字符串指向同一个对象,pycharm自动对字符串进行了该处理
字符串连接,推荐用.join(),因为只new一次对象,比“+”效率高
4)list、tuple、dict、set
list=[1,2,4,"a",True,None]
list[2]#取值,list的结构就是数组,和java不同的就是可以存储不同的类型
list[2]= 0#实现替换
print(list[2:6])、print(list[2:])、print(list[:6])、print(list[::-1]) #取出指定区间的元素,-1是倒序输出
list[1:3]=[] #相当于清空指定区域的值
list.index("a")#返回a的下标,从左到右第一个,还可以跟两个参数,圈定一定的范围,如果没有返回一个错误
list.append([1,2,3])#实现追加3个元素,但是用extend实现追加时候,是将extend中的内容,当做一个元素加入到list中
list.insert(2,"a") #在指定的下标处添加,原来的元素依次后移,不会覆盖,添加的内容可以为list,但是也是当做一个元素
list.pop()#删除最后一个元素,括号中加入下标,代表删除指定的元素
list.remove()#移除列表中的某个元素,默认是从左到右第一个匹配的元素
list.clear()#清除所有元素
sorted(list)#等价于list.sort(),但是sort是在list上修改,sorted产生了新的list,sorted(list,reverse=True)指定正序或者逆序
list2 = list.copy() #深拷贝,复制出一样的元素,但是list和list2的空间地址是不同的
"*".join(list)#将list中的元素,用*进行拼接
tuple=(1,2,3,[5,7]) #元组的元素是不能改变的,但是如果元素是列表,则列表里面的元素可以进行修改
tuple('a','b')#也可以用这种方式生成,若只含1个元素,则元素后加‘,’即可tuple('a',')
print(tuple1+tuple2) #元素合并
print(tuple*3)#元素复制
print('a' in tuple) #判断是否在元组中
print(tuple[3:6])#元素的截取
tuple=((1,2,3),(1,2,3),(1,2,3))
元组相对列表安全
dict1 = {"a":1,"b":2,"c":3}或者dict1 = dict('a'=1,'b'=2)
for i in dict1: #获取键,如果是dict.values()则取出值,进行遍历
print(i," ",dict1.get(i)) #如果不存在会返回None,或者dict1[i]
for i,j in dict1.items(): #获取键值对
print(i," ",j)
dict["d"]=5 #键存在则修改值,否则添加
dict.pop("d")#不能直接pop()
list=[10,30,20]
item=['a','b','c']
for i,j in zip(list,item):
print(i,j)#将两个列表组合成一个dict
set 无序、无重复,元素不能是list或者dict,无索引,用{}来指示说明是set类型
set ={1,2,3,1,2,4} #等于set ={1,2,3,4}
a = set({1,2,2,3})#另外一种声明方式
a.update([3])#追加一个元素
5)其他
import keyword
print(keyword.kwlist)#查看关键字
num1 = int(input("input a number")) #交互式输入一个int值
删除变量,del 变量名,例如:del num1
集合的操作
判断a是否是b的子集:issubset
判断a是否是b的超集:issuperset
判断a、b是否无交集:isdisjoint
并集|=union,交集&=intersection,差集-=difference,对称差集^=symmetric_difference
2.if、for、while
if、elif、else
list=[1,2,4,"a",True,None]
for i in list:
print(i)
for i,j in enumerate(["b",'a',"123"]):#可以通过i知道下标
print(i," ",j)
break#跳出距离最近的循环
for i in range(2):
pwd = input()
if pwd=='1':
print("right")
break
else:
print("wrong")
else:
print("sorry,no chance left")
#这里如果执行for结束后还是没有符合条件,将会执行else
3.函数
endstr = "end"#定义一个结束字符串
str = ""
for line in iter(input,endstr): #不断地输入,直到遇到endstr就停止,然后输出str
str += line +"\n"
print(str)
def print(b="ccc"): #b可以有默认参数
print("a")
def print1(**a): #**代表键值对的参数类型
print(a)
sum = lambda a,b: a+b #lambda就一行,很简单,定义a,b参数,输出相加结果
print(sum(1,2))
4.装饰器
闭包,把函数当做参数给一个函数,返回一个新的函数,类似装饰者模式
def p1(f):
def inner(): #内部定义一个函数,对传入的函数进行修饰
print("a")
f()
return inner #将修饰后的函数返回
def f1():
print("b")
i = p1(f1)
i() #执行修饰后的函数
def printage(func): #注意传入和返回的函数不加括号
def inner(age): #这里的age和sayage里面的age名称没有关系,不必保持一致
if age <0:
age = 0
func(age)
return inner
def sayage(age):
print(age)
p = printage(sayage)
p(-1)
或者直接采用@,替代printage(sayage),一样的效果
def printage(func):
def inner(age2):
if age2 <0:
age2 = 0
func(age2)
return inner@printage
def sayage(age):
print(age)sayage(-1)
#偏函数,把其中一个参数固定住
import functools
int2 = functools.partial(int,base=10)
print(int2("111"))
5.异常处理
def d(a,b):
try:
print(a/b)
except ZeroDivisionError as e: #或者直接except :这样可以匹配任何的异常,最后加finally 无论如何都会执行,和java一样
print("error")
else:
print("no problem")
d(1,1)
def func(a,b):
assert (b!=0),"b can not be zero" #提示信息
return a/b
func(1,0)
6.文件io
你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。语法:
file object = open(file_name [, access_mode][, buffering])
各个参数的细节如下:
file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
# 打开一个文件
fo = open("foo.txt", "w")str = fo.read() #获取文本内容 read(10) 读10个字符,如果继续读,指针会不断向后,而不会回到最初
fo.readline() #读取行
fo.readlines() #读取所有行,返回列表
fo.seek(10) #从第十个开始读
print "文件名: ", fo.name
print "是否已关闭 : ", fo.closed
print "访问模式 : ", fo.mode
print "末尾是否强制加空格 : ", fo.softspace以上实例输出结果:
文件名: foo.txt
是否已关闭 : False
访问模式 : w
末尾是否强制加空格 : 0
File 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。
语法:
fileObject.close()
write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
write()方法不会在字符串的结尾添加换行符('\n'):
语法:fileObject.write(string)
在这里,被传递的参数是要写入到已打开文件的内容。
例子:
# 打开一个文件
fo = open("foo.txt", "w")
fo.write( "www.runoob.com!\nVery good site!\n")fo.flush()#不等close,直接写出,缓冲区满也会写出
# 关闭打开的文件
fo.close()
with open("foo.txt","r") as f: #简洁写法,with可以自行关闭
print(f.read())
7.递归
def sum(a):
if a==1:
return 1
count = a+sum(a-1)
return count
print(sum(5))
8.队列、栈
#队列
import collections
q = collections.deque()
q.append(1)
q.append(2)
q.append(3)
q.popleft()
print(q)#栈
用list模拟即可
9.os
import os
def getdir(f):
dir = os.listdir(f)
for i in dir:
if os.path.isdir(os.path.join(f,i)): #判断是文件还是目录
print("文件夹 ",i )
else:
print("文件 ",i)
10.时间
import time # 引入time模块
ticks = time.time()
print("当前时间戳为:", ticks)
获取当前时间
从返回浮点数的时间戳方式向时间元组转换,只要将浮点数传递给如localtime之类的函数。
import time localtime = time.localtime(time.time())
print( "本地时间为 :", localtime)
以上实例输出结果:
本地时间为 : time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=3, tm_sec=27, tm_wday=3, tm_yday=98, tm_isdst=0)
格式化日期
我们可以使用 time 模块的 strftime 方法来格式化日期,:
time.strftime(format[, t])
实例演示:
实例(Python 2.0+)
import time
# 格式化成2016-03-20 11:45:39形式
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# 格式化成Sat Mar 28 22:24:24 2016形式
print time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
# 将格式字符串转换为时间戳 a = "Sat Mar 28 22:24:24 2016"
print time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y"))
以上实例输出结果:
2016-04-07 10:25:09
Thu Apr 07 10:25:09 2016
1459175064.0
11.模块
#在模块day1中,这里如果直接执行day1,会执行main,不会执行else中部分
if __name__=="__main__":
print("jj")
else:
def sayhello():
print("gg")
#day2中引用
import day1
day1.sayhello()
Python中的包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。
考虑一个在 package_runoob 目录下的 runoob1.py、runoob2.py、__init__.py 文件,test.py 为测试调用包的代码,目录结构如下:
test.py
package_runoob
|-- __init__.py
|-- runoob1.py
|-- runoob2.py源代码如下:
package_runoob/runoob1.py
#!/usr/bin/python # -*- coding: UTF-8 -*-
def runoob1():
print "I'm in runoob1"
package_runoob/runoob2.py
#!/usr/bin/python # -*- coding: UTF-8 -*-
def runoob2():
print "I'm in runoob2"
现在,在 package_runoob 目录下创建 __init__.py:
package_runoob/__init__.py
#!/usr/bin/python # -*- coding: UTF-8 -*-
if __name__ == '__main__':
print '作为主程序运行'
else:
print 'package_runoob 初始化'
然后我们在 package_runoob 同级目录下创建 test.py 来调用 package_runoob 包
test.py
#!/usr/bin/python # -*- coding: UTF-8 -*- # 导入 Phone 包
from package_runoob.runoob1 import runoob1
from package_runoob.runoob2 import runoob2
runoob1()
runoob2()
以上实例输出结果:
package_runoob 初始化
I'm in runoob1
I'm in runoob2如上,为了举例,我们只在每个文件里放置了一个函数,但其实你可以放置许多函数。你也可以在这些文件里定义Python的类,然后为这些类建一个包。
12.面向对象
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。
class Employee:
'所有员工的基类'
empCount = 0def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1def displayCount(self):
print("Total Employee %d" % Employee.empCount)def displayEmployee(self):
print("Name : ", self.name, ", Salary: ", self.salary)
empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。
第一种方法__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类。
实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。
以下使用类的名称 Employee 来实例化,并通过 __init__ 方法接收参数。
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)可以使用点号 . 来访问对象的属性。使用如下类的名称访问类变量: Employee.empCount
也可以使用以下函数的方式来访问属性:
- getattr(obj, name[, default]) : 访问对象的属性。
- hasattr(obj,name) : 检查是否存在一个属性。
- setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
- delattr(obj, name) : 删除属性。
hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True。 getattr(emp1, 'age') # 返回 'age' 属性的值 setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8 delattr(emp1, 'age') # 删除属性 'age'
- __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
- __doc__ :类的文档字符串
- __name__: 类名
- __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
- __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
执行以上代码输出结果如下:
Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = ydef __del__(self):
class_name = self.__class__.__name__
print(class_name, "销毁")pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3)) # 打印对象的id
del pt1
del pt2
del pt3
13.继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
继承语法
class 派生类名(基类名) ...
class Parent: # 定义父类 parentAttr = 100 def __init__(self): print "调用父类构造函数" def parentMethod(self): print '调用父类方法' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "父类属性 :", Parent.parentAttr class Child(Parent): # 定义子类 def __init__(self): print "调用子类构造方法" def childMethod(self): print '调用子类方法' c = Child() # 实例化子类 c.childMethod() # 调用子类的方法 c.parentMethod() # 调用父类方法 c.setAttr(200) # 再次调用父类的方法 - 设置属性值 c.getAttr() # 再次调用父类的方法 - 获取属性值
可以继承多个类
class A: # 定义类 A ..... class B: # 定义类 B ..... class C(A, B): # 继承类 A 和 B
class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self, other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2, 10) v2 = Vector(5, -2) print(v1 + v2) 以上代码执行结果如下所示: Vector(7, 8)
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
实例
class JustCounter: __secretCount = 0 # 私有变量 publicCount = 0 # 公开变量 def count(self): self.__secretCount += 1 self.publicCount += 1 print(self.__secretCount) counter = JustCounter() counter.count() counter.count() print(counter.publicCount print(counter.__secretCount) # 报错,实例不能访问私有变量
Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性,参考以下实例: #!/usr/bin/python # -*- coding: UTF-8 -*- class Runoob: __site = "www.runoob.com" runoob = Runoob() print(runoob._Runoob__site) 执行以上代码,执行结果如下: www.runoob.com
单下划线、双下划线、头尾双下划线说明:
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。