Python3基础知识整理(一)

三目运算

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)

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

 

List相关 

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基本方法相关

生命周期相关

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.包的概念

Python3基础知识整理(一)_第1张图片

TestMsg是文件夹,如果外部使用import TesmMsg想要使用py模块,需要用到__init__.py的文件,类似于一个文件,把里面的所有py模块头文件包含在一个文件里面,两种方式都行

Python3基础知识整理(一)_第2张图片

 

Python3面向对象(2)

Python3线程(3)

 

你可能感兴趣的:(Python3学习)