Python拾遗、Python高级编程

-10 读取txt中的图片name返回list 用在 pytorch dataset中

def __init__(self, path_rgb, path_sn, transform= None):
        self.transform= transform
        data= open(path_rgb)
        self.rgb_list = data.readlines()
        for l in self.rgb_list:
            l= l.strip('\n').strip('\n')
        data.close()

        data= open(path_sn)
        self.sn_list = data.readlines()
        for l in self.sn_list:
            l= l.strip('\n').strip('\n')
        data.close()

-9  python // 与 / 的含义

   1   在 Python 2.2  :

         要引用: from __future__ import division
  
     	" / "就表示 浮点数除法,返回浮点结果;" // "表示整数除法。

   2    Python 3以后  :
    	" / "就表示 浮点数除法,返回浮点结果;" // "表示整数除法。

python高级编程

https://zhuanlan.zhihu.com/p/33517855?utm_source=wechat_session

-8.  a[::-1]翻转

设有一个元组或者列表

a = (1,2,3,4)
b = [1,2,3,4]

则a[::-1]和b[::-1]的含义是将元组或列表的内容翻转

a[::-1]  # 结果为(4,3,2,1)
b[::-1]  #结果为[4,3,2,1]

注意和a[:-1]的区别

a[:-1]表示从元组中切片,默认从第一个元素开始,到倒数第一个元素前面的那个元素为止

a[:-1] #结果为(1,2,3)
b[:-1] #结果为[1,2,3]
>>> a=[1,2,3,4,5,6,7,8,9]
>>> print(a[::2])
[1, 3, 5, 7, 9]

-7.Python中a和a[:]有什么区别?

[]是引用 传址调用
[:] 是复制 传值调用

发现用b=a[:], 再给b赋值, 不会影响a; 直接给a[:]赋值却会影响a

python 深入理解 赋值、引用、拷贝、作用域

https://www.cnblogs.com/jiangzhaowei/p/5740913.html

-6.装饰器

装饰器本质是一个python函数,如果学过flask就知道,里边装饰器是必须的,经常用到。

装饰器的作用:抽离大量和函数功能本身无关的代码进行重用

一个简单的装饰器,用于计数,由于对不同的函数运行时间进行计数的需要,所以要对时间计数这部分进行处理。

def get_time(func):
	def wrapper():
        startTime = time.time()
        func()
        endTime = time.time()
        print("spend %f" % (endTime-startTime))
    return wrapper
myFunction = get_time(myFunction)
	

精简一下,使用@语法来进行精简:

import time
def get_time(func):
    startTime = time.time()
    func()
    endTime = time.time()
    processTime = (endTime - startTime) * 1000
    print ("The function timing is %f ms" %processTime)
    
@get_time
def myfunc():
	print("start")
	time.sleep(0.8)
	print("end")

if __name__ == "__main__":
    myfunc

output:

start
end
The function timing is 800.058126 ms

理解为:get_time(myfun()) ,将myfunc()函数包裹

装饰器可以叠加使用,若多个装饰器同时装饰一个函数,那么装饰器的调用顺序和@语法糖的声明顺序相反,也就是:

@decorator1
@decorator2
def func():
    pass

等效于:

func = decorator1(decorator2(func()))

-5.生成器

生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

使用了yield的函数被称为生成器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。(之前也遇见过yolo的代码中使用了这种用法,需要仔细理解并掌握)

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

-4. 迭代器

迭代器指的是可以使用next()方法来回调的对象,可以对可迭代对象使用iter()方法,将其转换为迭代器。

>>> L=[1,2,3,4,5]
>>> lst = iter(L)
>>> type(lst)

>>> L1=(1,2,3,4,5)
>>> lst1 = iter(L1)
>>> type(lst1)

>>> next(lst)
1
>>> next(lst1)
1
>>>

迭代器优势: 所有的元素不是一次性加载的,在调用next方法才会返回,不需要考虑内存问题。next()只能往后进行访问。

迭代器应用场景:

  1. list规模过大,出于对内存的考虑使用迭代器。
  2. 有规律,但是不能使用列表推导式描述

迭代器的创建:

  1. __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
  2. __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))

-3. enumerate内建函数

对于一个列表,既要遍历索引又要遍历元素。

>>> days=['mon','tus','wed','ths','fri','sat','sun']
>>> for i,day in enumerate(days):
...     print(i,day)
...
0 mon
1 tus
2 wed
3 ths
4 fri
5 sat
6 sun
>>> for i,day in enumerate(days, start=1):
...     print(i,day)
...
1 mon
2 tus
3 wed
4 ths
5 fri
6 sat
7 sun
>>>

-2.列表解析式

列表解析式是Python内置的非常简单强大的可以用来创建list的生成式。在深度学习项目中也可以经常看到这种用法。

(1) 语法1:[表达式 for 变量 in 列表],表示把得到的每一个变量值都放到 for 前面的表达式中计算 ,然后生成一个列表
(2) 语法2:[表达式 for 变量 in 列表 if 条件],如果加上 if 判断,则表示把每一个变量值进行判断,如果判断正确再交给表达式进行计算,然后生成一个列表

举例:

>>> items=[1,2,3,4,5,6,7]
>>> [item*2 for item in items]
[2, 4, 6, 8, 10, 12, 14]
>>> [item*2 for item in items if item % 2 == 0]
[4, 8, 12]

-1.闭包

当一个函数定义在另一个函数内,且使用到了外部函数的参数。整个代码块称为闭包。当外部参数确定时,内部函数参数可以反复调用。

def num(num): #定义函数
	def num_in(nim_in): #定义函数
		return num + num_in #返回两个参数的和。
	return num_in #返回内部函数的引用。(变量名)
 
a = num(100) #将参数为100的函数num接收,并赋值给a,只不过这个返回值是一个函数的引用。等于 a = num_in,注意这里接收的不光是函数本身,还有已经传递的参数。
b = a(100) #调用函数a,即num_in,并传递一个参数100,返回值给b。

0.lambda匿名函数

匿名函数就是没有定义函数的名称,用来实现简单的功能。

语法结构:lambda param_list: expression

param_list 就是参数列表,相当于函数的参数

expression 就是表达式,相当于函数体,用一行进行表示

>>> func=lambda x, y: x+y
>>> func(3,4)
7

1. Python 字符串前面加u,r,b的含义。 

  1. 加u,我是含有中文字符的字符串。后面的字符串以Unicode格式进行编码,一般用在中文字符串前面,防止因为源码存储格式问题,导致再次使用时出现乱码。
  2. 加r,表示后面试一个普通的字符串。去掉反斜杠的转移机制。
  3. 加b,表示后面的字符串是bytes类型。网络编程中,服务器和浏览器只认bytes类型数据。

2. Python面向对象

面向对象技术简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
  • __init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法

  • self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

  • self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类。

    self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的

  •  Python 中并没有new这个关键字,类的实例化类似函数调用方式。

    使用类的名称来实例化,并通过 __init__ 方法接收参数。

  • 使用点号 . 来访问对象的属性。

  • 可以使用以下函数的方式来访问属性:

  1. getattr(obj, name[, default]) : 访问对象的属性。
  2. hasattr(obj,name) : 检查是否存在一个属性。
  3. setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
  4. delattr(obj, name) : 删除属性。
  • Python内置类属性

  1. __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  2. __doc__ :类的文档字符串
  3. __name__: 类名
  4. __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  5. __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

python对象销毁(垃圾回收)

Python 使用了引用计数这一简单技术来跟踪和回收垃圾。在 Python 内部记录着所有使用中的对象各有多少引用。一个内部跟踪变量,称为一个引用计数器。当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。

析构函数 __del__ ,__del__在对象销毁的时候被调用

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class Point:
   def __init__( self, x=0, y=0):
      self.x = x
      self.y = y
   def __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

类的继承 https://www.runoob.com/python/python-object.html

class 派生类名(基类名)

3. 单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。

  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

4. 运算符重载

#!/usr/bin/python
 
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

 

你可能感兴趣的:(Python拾遗、Python高级编程)