res = 条件成立语句 if 条件 else 条件不成立的语句
res = a if a > b else b #条件放在了中间
匿名函数
可以自己写死匿名函数或者通过用户手动动态键入 lambda 无return字段,自带return参数
1 #coding=utf-8
2 #infors = [{"name":"mikejing","age":10},{"name":"jiaojiao","age":20},{"name":"caicai","age":30}]
3 #infors.sort(key = lambda x:x["name"])
4 #printn(infors)
5
6 #def test(a,b,func):
7 # result = func(a,b)
8 # return result
9
10 #fun_input = input("请输入一个匿名函数")
11 #num = test(11,22,fun_input)
12 #print(num)
注意点:python2和3里面有一个区别是是否要加coding=utf-8,还有一个区别就是input函数的区别
14 num = input("输入")
15 print(num)
mintoudeMacBook-Pro:py mintou$ python niminghanshu.py
输入1+2
3
mintoudeMacBook-Pro:py mintou$ python3 niminghanshu.py
输入1+2
1+2
可以看出python2的input是结果运算,python3的input是字符串,无论你输入什么,都是把整个一坨先整理成字符串,在通过eval转换
eval 例如你输入一个字符串,你转换成函数或者列表,不能加前缀转,需要用eval。
就好比把字典写入文件,然后你转换成字符串,然后写入,你读取的时候不能用list(str)来转换,你需要用eval来得到转换前的list
6 def test(a,b,func):
7 result = func(a,b)
8 return result
9
10 fun_input = input("请输入一个匿名函数")
11 # "lambda x,y:x+y" python3里面是字符串
12 fun_input = eval(fun_input)
13 # lambda x,y:x+y python3里面是字符转换成函数 eval
14 num = test(11,22,fun_input)
15 print(num)
这样就不会再python3里面崩掉了
函数返回多个值
>>> def divid(a, b):
... shang = a//b
... yushu = a%b
... return shang, yushu
...
>>> sh, yu = divid(5, 2)
>>> sh
5
>>> yu
1
实际上就是返回的元祖,外部可以直接赋值使用
函数参数缺省
def printinfo( name, age = 35 ):
# 打印任何传入的字符串
print ("Name: ",name)
print ("Age ", age)
# 调用printinfo函数
printinfo("midsdsi" )
printinfo( age=9,name="miki" )
不定长参数测试
>>> 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
...
>>> fun(1, 2, 3, 4, 5, m=6, n=7, p=8) # 注意传递的参数对应
a = 1
b = 2
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) # 注意元组与字典的传参方式
a = 1
b = 2
args = (3, 4, 5)
kwargs:
p = 8
m = 6
n = 7
>>>
>>>
>>>
>>> fun(1, 2, c, d) # 注意不加星号与上面的区别
a = 1
b = 2
args = ((3, 4, 5), {'p': 8, 'm': 6, 'n': 7})
kwargs:
>>>
>>>
加了星号(*)的变量args会存放所有未命名的变量参数,args为元组;而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。
函数参数陷阱
def test1(list=[],item=None):
list.append(item)
return list
t1 = test1(item="111")
print(t1)
t2 = test1(item="2222")
print(t2)
# ['111']
# ['111', '2222']
这里如果你给了函数参数一个默认可变类型的容器,字典或者数组,就会遇到上面的情况,理论上这是一个Bug,先介绍下Python变量的本质
要了解这个问题的原因我们先需要一个准备知识,那就是:Python变量到底是如何实现的? Python变量区别于其他编程语言的申明&赋值方式,采用的是创建&指向的类似于指针的方式实现的。即Python中的变量实际上是对值或者对象的一个指针(简单的说他们是值得一个名字)。我们来看一个例子。
p = 1
p = p+1
对于传统语言,上面这段代码的执行方式将会是,先在内存中申明一个p
的变量,然后将1
存入变量p
所在内存。执行加法操作的时候得到2
的结果,将2
这个数值再次存入到p
所在内存地址中。可见整个执行过程中,变化的是变量p
所在内存地址上的值 上面这段代码中,Python实际上是现在执行内存中创建了一个1
的对象,并将p
指向了它。在执行加法操作的时候,实际上通过加法操作得到了一个2
的新对象,并将p
指向这个新的对象。可见整个执行过程中,变化的是p
指向的内存地址
Python函数的参数默认值,是在编译阶段就绑定的
如果参数默认值在编译阶段就已经被绑定,那么如果参数不给值,直接用默认的,那这个值就是指向编译已经生成的对象的地址。如果参数的默认值是个不可变类型,参数在函数体内修改了值,那么参数就会指向新的值。那么如果是可变类型,函数体内的操作实际上就是对编译阶段已经生成的对象的修改。
避免这个机制带来的问题
def test1(list=None,item=None):
if list is None:
list = []
list.append(item)
return list
a += b 和 a = a + b的区别
>>> def selfAdd(a):
... """自增"""
... a += a
...
>>> a_int = 1
>>> a_int
1
>>> selfAdd(a_int)
>>> a_int
1
>>> a_list = [1, 2]
>>> a_list
[1, 2]
>>> selfAdd(a_list)
>>> a_list
[1, 2, 1, 2]
>>> def selfAdd(a):
... """自增"""
... a = a + a # 我们更改了函数体的这句话
...
>>> a_int = 1
>>> a_int
1
>>> selfAdd(a_int)
>>> a_int
1
>>> a_list = [1, 2]
>>> a_list
[1, 2]
>>> selfAdd(a_list)
>>> a_list
[1, 2] # 想一想为什么没有变呢?
a = ["1","2","3",3]
b = a
print(a) # ['1', '2', '3', 3]
print(b) # ['1', '2', '3', 3]
print(a.__iadd__("3")) # ['1', '2', '3', 3, '3']
print(a) # ['1', '2', '3', 3, '3']
print(b) # ['1', '2', '3', 3, '3']
c = ["a","b","c","d"]
d = c
print(c) # ['a', 'b', 'c', 'd']
print(d) # ['a', 'b', 'c', 'd']
print(c.__add__(["x"])) # ['a', 'b', 'c', 'd', 'x']
print(c) # ['a', 'b', 'c', 'd']
print(d) # ['a', 'b', 'c', 'd']
针对字符串,数字,元祖不可变类型
a += a 和 a = a + a 都是一样的,产生一个新的对象
如果是可变对象list或者dict
a += a 和 a = a + a 不一样的,前者引用操作,改变原资源,后者生成新的对象,不改变原资源
+= 操作调用 __iadd__方法,没有该方法时,再尝试调用__add__方法
__iadd__方法直接在原对象a上进行更新,该方法的返回值为None
+ 操作调用__add__方法
__add__方法会返回一个新的对象,原对象不修改,因为这里 a被重新赋值了
A 和 B两个参数的交换
a = 10
b = 20
# 第一种
# c = 0
# c = a
# a = b
# b = c
# print("a=(%d),b=(%d)"%(a,b))
# 第二种
# a = a + b
# b = a - b
# a = a - b
# print("a=(%d),b=(%d)"%(a,b))
# 第三种
a,b = b,a
print("a=(%d),b=(%d)"%(a,b))
type(object) 查看数据类型
id(object) 查看内存地址
字符串分割和拼接 split 和 join
In [3]: a = "a,b,n"
In [4]: a.split(",")
Out[4]: ['a', 'b', 'n']
In [11]: a = ["a","b","c"]
In [12]: c = "#"
In [13]: c.join(a)
Out[13]: 'a#b#c'
字符串截取 和 逆序输出
In [15]: a = "abcdef"
In [16]: a[2:]
Out[16]: 'cdef'
In [17]: a[2:5]
Out[17]: 'cde'
In [18]: a[2:-1]
Out[18]: 'cde'
In [19]: a[:-1]
Out[19]: 'abcde'
In [21]: a[-1:0:-1]
Out[21]: 'fedcb'
In [22]: a[::-1]
Out[22]: 'fedcba'
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | 10+20 输出结果 30 |
- | 减 - 得到负数或是一个数减去另一个数 | 10-20 输出结果 -10 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | 10 * 20 输出结果 200 |
/ | 除 - x除以y | 20/10 输出结果 2 |
% | 取余 - 返回除法的余数 | 20%10 输出结果 0 |
** | 幂 - 返回x的y次幂 | 10**2 输出结果 100 |
// | 取整除 - 返回商的整数部分 | 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
运算符 | 描述 | 实例 |
---|---|---|
and | 布尔"与" - 如果x为False,x and y返回False,否则它返回y的计算值。 | (a and b) 返回 true。 |
or | 布尔"或" - 如果x是True,它返回True,否则它返回y的计算值。 | (a or b) 返回 true。 |
not | 布尔"非" - 如果x为True,返回False。如果x为False,它返回True。 | not(a and b) 返回 false。 |
注:字符串,数字,元祖不可变,其他类型都是可变的,因此字典的key只能是前三个
In [1]: a = {'a':123,'b':456}
In [2]: a
Out[2]: {'a': 123, 'b': 456}
In [3]: a.has_key('a')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in ()
----> 1 a.has_key('a')
AttributeError: 'dict' object has no attribute 'has_key'
以上是2.7版本的API,3以后就没用了
3以后用这个
In [6]: 'a' in a
Out[6]: True
help(list) 查看所有相关list信息
extend
In [24]: a = ["11","22"]
In [25]: b = ["33","44"]
In [26]: a.extend(b)
In [27]: a
Out[27]: ['11', '22', '33', '44']
In [28]: c = "afvc"
In [29]: a.extend(c)
In [30]: a
Out[30]: ['11', '22', '33', '44', 'a', 'f', 'v', 'c']
append
In [31]: a = ["aa","bb"]
In [32]: b = ["cc","dd"]
In [33]: a.append(b)
In [34]: a
Out[34]: ['aa', 'bb', ['cc', 'dd']]
In [35]: c = "ee"
In [36]: a.append(c)
In [37]: a
Out[37]: ['aa', 'bb', ['cc', 'dd'], 'ee']
extend是拆分出来组成新的数组,append是当成整体组成新的数组
insert插入数组 和 append不同必须带有两个参数
In [39]: a = ["a","b","c"]
In [40]: a.append("d")
In [41]: a
Out[41]: ['a', 'b', 'c', 'd']
In [42]: a.insert("e")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
----> 1 a.insert("e")
TypeError: insert() takes exactly 2 arguments (1 given)
In [43]: a.insert(0,"e")
In [44]: a
Out[44]: ['e', 'a', 'b', 'c', 'd']
In [45]: a.insert(6,"f")
In [46]: a
Out[46]: ['e', 'a', 'b', 'c', 'd', 'f']
In [47]: a.insert(100,"f")
In [48]: a
Out[48]: ['e', 'a', 'b', 'c', 'd', 'f', 'f']
In [49]: a.insert(-1,"f")
In [50]: a
Out[50]: ['e', 'a', 'b', 'c', 'd', 'f', 'f', 'f']
remove相关
>>> all_users
['python', 'qiwsir', 'github', 'io', 'algorithm']
>>> "python" in all_users #这里用in来判断一个元素是否在list中,在则返回True,否则返回False
True
>>> if "python" in all_users:
... all_users.remove("python")
... print all_users
... else:
... print "'python' is not in all_users"
...
['qiwsir', 'github', 'io', 'algorithm'] #删除了"python"元素
>>> if "python" in all_users:
... all_users.remove("python")
... print all_users
... else:
... print "'python' is not in all_users"
...
'python' is not in all_users #因为已经删除了,所以就没有了
enumerate
In [57]: for i,str in enumerate(a):
...: print("index = %d,str = %s"%(i,str))
...:
index = 0,str = 111
index = 1,str = 222
index = 2,str = 333
元组是用圆括号括起来的,其中的元素之间用逗号隔开。(都是英文半角)
用途:
在很多时候,的确是用list和str都可以了。但是,看官忘记,我们用计算机语言解决的问题不都是简单问题,就如同我们的自然语言一样,虽然有的词汇看似可有可无,用别的也能替换之,但是我们依然需要在某些情况下使用它们.
一般认为,tuple有这类特点,并且也是它使用的情景:
- Tuple 比 list 操作速度快。如果您定义了一个值的常量集,并且唯一要用它做的是不断地遍历它,请使用 tuple 代替 list。
- 如果对不需要修改的数据进行 “写保护”,可以使代码更安全。使用 tuple 而不是 list 如同拥有一个隐含的 assert 语句,说明这一数据是常量。如果必须要改变这些值,则需要执行 tuple 到 list 的转换 (需要使用一个特殊的函数)。
- Tuples 可以在 dictionary 中被用做 key,但是 list 不行。实际上,事情要比这更复杂。Dictionary key 必须是不可变的。Tuple 本身是不可改变的,但是如果您有一个 list 的 tuple,那就认为是可变的了,用做 dictionary key 就是不安全的。只有字符串、整数或其它对 dictionary 安全的 tuple 才可以用作 dictionary key。
- Tuples 可以用在字符串格式化中,上面也有用到
tree无法打印中文 用tree -N
模式 | 描述 |
---|---|
r | 以读方式打开文件,可读取文件信息。 |
w | 以写方式打开文件,可向文件写入信息。如文件存在,则清空该文件,再写入新内容 |
a | 以追加模式打开文件(即一打开文件,文件指针自动移到文件末尾),如果文件不存在则创建 |
r+ | 以读写方式打开文件,可对文件进行读和写操作。 |
w+ | 消除文件内容,然后以读写方式打开文件。 |
a+ | 以读写方式打开文件,并把文件指针移到文件尾。 |
b | 以二进制模式打开文件,而不是以文本模式。该模式只对Windows或Dos有效,类Unix的文件是用二进制模式进行操作的。 |
文件CopyDemo
如果一个文件很大,比如5G,试想应该怎样把文件的数据读取到内存然后进行处理呢?
def getNewFileName(originName):
dot_p = file_name.rfind(".")
print(dot_p)
pre_name = file_name[0:dot_p]
pre_name = "%s[副本]"%pre_name
print(pre_name)
new_file_name = "%s%s"%(pre_name,file_name[dot_p:])
print(new_file_name)
return new_file_name
file_name = input("请输入需要copy的文件名")
# 只读打开
f_origin = open(file_name,"r")
new_file_name = getNewFileName(file_name)
#print(new_file_name)
# 读写,不存在就创建
f_new = open(new_file_name,"w")
while true:
# 读取文件
content = f_origin.read(1024)
if len(content) == 0:
break
# 写入
f_new.write(content)
f_new.close()
f_origin.close()
OS模块
In [12]: os.getcwd()
Out[12]: '/Users/mintou/Desktop/py'
In [13]: os.listdir()
Out[13]: ['.DS_Store', '2-test.py', '222.py', '.vimrc', '1-test[副本].py']
In [14]: os.chdir(../)
File "", line 1
os.chdir(../)
^
SyntaxError: invalid syntax
In [15]: os.chdir("../")
In [16]: os.getcwd()
Out[16]: '/Users/mintou/Desktop'
getcwd获取到的是open文件创建文件的目录,可以chdir进行修改,可以用listdir列出指定目录下的文件名
批量重命名
import os
file_name = input("请输入需要替换文件名的文件夹")
files = os.listdir(file_name)
#os.chdir(file_name)
for name in files:
os.rename(file_name+"/"+name,"%s%s"%("娇娇-",name))
生命周期相关
class Dog(object):
# 只负责初始化
def __init__(self):
print("----init方法-----")
# 对象dealloc的时候调用
def __del__(self):
print("----del方法-----")
# description方法
def __str__(self):
print("----str方法-----")
return "对象的描述信息"
# 类似OC里面的alloc 只负责创建对象
def __new__(cls):#cls此时是Dog指向的那个类对象
#print(id(cls))
print("----new方法-----")
# 调用父类的方法去分配空间并返回给init初始化
return object.__new__(cls)
#print(id(Dog))
xtq = Dog()
单例设计模式
# __new__ 方法创建 类和对象
class SingleTon(object):
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super(SingleTon, cls).__new__(cls, *args, **kwargs)
return cls.__instance
class Banaber(SingleTon):
a = 1
# __call__ 方法创建 元类和类
class SingleTon(type):
__intance = None
def __call__(self, *args, **kwargs):
if self.__intance is None:
self.__intance = super().__call__(*args, **kwargs)
return self.__intance
class Foo(metaclass=SingleTon):
pass
工厂设计模式
class Store(object):
def select_car(self):
pass
def order(self, car_type):
return self.select_car(car_type)
class BMWCarStore(Store):
def select_car(self, car_type):
return BMWFactory().select_car_by_type(car_type)
class BMWFactory(object):
def select_car_by_type(self, car_type):
pass
# if car_type=="mini":
# return Suonata()
# elif car_type=="720li":
# return Mingtu()
# elif car_type=="x6":
# return Ix35()
bmw_store = BMWCarStore()
bmw = bmw_store.order("720li")
class CarStore(Store):
def select_car(self, car_type):
return Factory().select_car_by_type(car_type)
class Factory(object):
def select_car_by_type(self, car_type):
if car_type=="索纳塔":
return Suonata()
elif car_type=="名图":
return Mingtu()
elif car_type=="ix35":
return Ix35()
模块相关
解压 tar -zxvf
安装 python3 setup.py install
1.__name__ == "__main__" YES的时候是python xxx.py自调用使用,别人使用模块就能屏蔽掉
2.包的概念
TestMsg是文件夹,如果外部使用import TesmMsg想要使用py模块,需要用到__init__.py的文件,类似于一个文件,把里面的所有py模块头文件包含在一个文件里面,两种方式都行
Python3面向对象(2)
Python3线程(3)