python

1.析构问题:

python

import gc

#del之后 调用gc.collect()

#当有数据写入硬盘的时候,一定要显式清空变量内的数据

 templist  = templist[:]

 del templist

  gc.collect()

2.2b 语法

class UpperAttrMetaClass(type):
    def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr):
        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)
        return type(future_class_name, future_class_parents, uppercase_attr)

####

a = [1,2,3,4,5,6]
b = (value for value in a if value < 5)
print type(b) --------------->is a generator
for i in b:
    print i

怎样创建一个python generator?

就像创建一个函数一样简单,只不过不使用return 声明,而是使用yield声明.

如果一个函数至少包含一个yield声明(当然它也可以包含其他yield或return),那么它就是一个generator. 

yield和return都会让函数返回一些东西,区别在于,return声明彻底结束一个函数,而yield声明是暂停函数,保存它的所有状态,并且后续被调用后会继续执行.

generator函数和普通函数的区别

  • generator函数包含一个以上的yield声明
  • generator函数被调用的时候,会返回一个iterator对象,但是函数并不会立即开始执行
  • __iter__()和__next__()方法被自动实现,所以可以使用next()函数对返回的此iterator对象进行迭代
  • 一旦一个generator 执行到yield语句,generator函数暂停,程序控制流被转移到调用方
  • 在对generator的连续调用之间,generator的本地变量和状态会被保存
  • 最终,generator函数终止,再调用generator会引发StopIteration异
  • 下面这个例子说明上述全部要点,我们有一个名为my_gen()的函数,它带有一些yield声明.
# A simple generator function  
def my_gen():  
    n = 1  
    print('This is printed first')  
    # Generator function contains yield statements  
    yield n  
  
    n += 1  
    print('This is printed second')  
    yield n  
  
    n += 1  
    print('This is printed at last')  
    yield n  

a = my_gen()
a.next()
a.next()
b = my_gen()
b.next()

This is printed first
This is printed second
This is printed first
View Code
通常来说,generator都是和循环结合实现的,且这个循环带有一个终止条件。

我们来看一个reverse一个字符串的例子

def rev_str(my_str):  
    length = len(my_str)  
    for i in range(length - 1,-1,-1):  
        yield my_str[i]  
  
# For loop to reverse the string  
# Output:  
# o  
# l  
# l  
# e  
# h  
for char in rev_str("hello"):  
     print(char)  
View Code

python generator 表达式

使用generator表达式可以很容易地创建简单的generator。

就像lambda函数可以创建匿名函数一样,generator函数创建一个匿名generator函数。

generator表达式的语法类似于python的list comprehension,只是方括号被替换为了圆括号而已。

list comprehension和generator表达式的主要区别在于,前者产生全部的list,后者每次仅产生一项。

它们有些懒惰,仅在接到请求的时候才会产生输出。因此,generator表达式比list comprehension更加节省内存。

# Initialize the list  
my_list = [1, 3, 6, 10]  
  
# square each term using list comprehension  
# Output: [1, 9, 36, 100]  
[x**2 for x in my_list]  
  
# same thing can be done using generator expression  
# Output: <generator object <genexpr> at 0x0000000002EBDAF8>  
(x**2 for x in my_list)  

上面的例子中,generator表达式没有立即产生需要的结果,而是在需要产生item的时候返回一个generator对象。

 

# Intialize the list  
my_list = [1, 3, 6, 10]  
  
a = (x**2 for x in my_list)  
# Output: 1  
print(next(a))  
  
# Output: 9  
print(next(a))  
  
# Output: 36  
print(next(a))  
  
# Output: 100  
print(next(a))  
  
# Output: StopIteration  
next(a)  
View Code

generator表达式可以在函数内部使用。当这样使用的时候,圆括号可以丢弃。

python里为什么要使用generator?

1.容易实现

相对于iterator类来说,generator的实现清晰、简洁。下面是用iterator实现一个2的指数函数

class PowTwo:  
    def __init__(self, max = 0):  
        self.max = max  
  
    def __iter__(self):  
        self.n = 0  
        return self  
  
    def __next__(self):  
        if self.n > self.max:  
            raise StopIteration  
  
        result = 2 ** self.n  
        self.n += 1  
        return result  

generator这样实现

 

def PowTwoGen(max = 0):  
    n = 0  
    while n < max:  
        yield 2 ** n  
        n += 1  
View Code

因为generator自动跟踪实现细节,因此更加清晰、简洁。

2.节省内存

一个函数返回一个序列(sequence)的时候,会在内存里面把这个序列构建好再返回。如果这个序列包含很多数据的话,就过犹不及了。

而如果序列是以generator方式实现的,就是内存友好的,因为他每次只产生一个item。

 缺点:由于每次只生成一个item 那么之前的数据就会消失,除非你拷贝出来

super():

super() 函数用于调用下一个父类(超类)并返回该父类实例的方法。

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。

issubclass():

issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类。issubclass(class, classinfo);

*argparse module

是python的一个命令行解析包,可以用来指定参数。

直接输入的参数:

#pro.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    'format',
    nargs='?',
    default='simple',
    help='the output format',
)

python pro.py sss
输出:
sss
View Code

输入指定的参数:

-v是短参数,--verbosity是长参数。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
        print "verbosity turned on"

>python prog.py -v 1
verbosity turned on

>python prog.py --verbosity 1
verbosity turned on

>python prog.py -h           
usage: prog.py [-h] [-v VERBOSITY]

optional arguments:
  -h, --help            show this help message and exit
  -v VERBOSITY, --verbosity VERBOSITY
                        increase output verbosity

>python prog.py -v 
usage: prog.py [-h] [-v VERBOSITY]
prog.py: error: argument -v/--verbosity: expected one argument
View Code

action='store_true':

-v没有指定任何参数也可,其实存的是TrueFalse,如果出现,则其值为True,否则为False.

#!/usr/bin/env python
# encoding: utf-8
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
                    action="store_true")
args = parser.parse_args()
if args.verbose:
        print "verbosity turned on"
View Code

类型 type:

#!/usr/bin/env python
# encoding: utf-8
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('x', type=int, help="the base")
args = parser.parse_args()
answer = args.x ** 2
print answer
View Code

可选值choices=[]:

#!/usr/bin/env python
# encoding: utf-8
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer
View Code

 

 程序用法帮助:

parser = argparse.ArgumentParser(description="calculate X to the power of Y")

互斥参数:

group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")

第一行定义了一个互斥组,第二、三行在互斥组中添加了-v-q两个参数.可以看出,-q-v不出现,或仅出现一个都可以,同时出现就会报错。可定义多个互斥组.

Python 模块导入:

在没有明确指定包结构的情况下,Python 是根据 __name__ 来决定一个模块在包中的结构的,如果是 __main__ 则它本身是顶层模块,没有包结构,如果是A.B.C 结构,那么顶层模块是 A。基本上遵循这样的原则:

  • 如果是绝对导入,一个模块只能导入自身的子模块或和它的顶层模块同级别的模块及其子模块
  • 如果是相对导入,一个模块必须有包结构且只能导入它的顶层模块内部的模块

如果一个模块被直接运行,则它自己为顶层模块,不存在层次结构,所以找不到其他的相对路径。

Python2.x 缺省为相对路径导入,Python3.x 缺省为绝对路径导入。绝对导入可以避免导入子包覆盖掉标准库模块(由于名字相同,发生冲突)。如果在 Python2.x 中要默认使用绝对导入,可以在文件开头加入如下语句:

from __future__ import absolute_import

from __future__ import absolute_import

这句 import 并不是指将所有的导入视为绝对导入,而是指禁用 implicit relative import(隐式相对导入), 但并不会禁掉 explicit relative import(显示相对导入)。

那么到底什么是隐式相对导入,什么又是显示的相对导入呢?我们来看一个例子,假设有如下包结构:

那么如果在 stool 中引用 bench,则有如下几种方式:

import bench                 # 此为 implicit relative import
from . import bench          # 此为 explicit relative import
from furniture import bench  # 此为 absolute import

隐式相对就是没有告诉解释器相对于谁,但默认相对与当前模块;而显示相对则明确告诉解释器相对于谁来导入。以上导入方式的第三种,才是官方推荐的,第一种是官方强烈不推荐的,Python3 中已经被废弃,这种方式只能用于导入 path 中的模块。

相对与绝对仅针对包内导入而言

最后再次强调,相对导入与绝对导入仅针对于包内导入而言,要不然本文所讨论的内容就没有意义。所谓的包,就是包含 __init__.py 文件的目录,该文件在包导入时会被首先执行,该文件可以为空,也可以在其中加入任意合法的 Python 代码。

相对导入可以避免硬编码,对于包的维护是友好的。绝对导入可以避免与标准库命名的冲突,实际上也不推荐自定义模块与标准库命令相同。

前面提到含有相对导入的模块不能被直接运行,实际上含有绝对导入的模块也不能被直接运行,会出现 ImportError.

##引用http://kuanghy.github.io/2016/07/21/python-import-relative-and-absolute

Pandas DataFrames 是个好工具

dict = {"country": ["Brazil", "Russia", "India", "China", "South Africa"],
       "capital": ["Brasilia", "Moscow", "New Dehli", "Beijing", "Pretoria"],
       "area": [8.516, 17.10, 3.286, 9.597, 1.221],
       "population": [200.4, 143.5, 1252, 1357, 52.98] }

import pandas as pd
brics = pd.DataFrame(dict)
print(brics)

     area    capital       country  population
0   8.516   Brasilia        Brazil      200.40
1  17.100     Moscow        Russia      143.50
2   3.286  New Dehli         India     1252.00
3   9.597    Beijing         China     1357.00
4   1.221   Pretoria  South Africa       52.98
# Set the index for brics
brics.index = ["BR", "RU", "IN", "CH", "SA"]

# Print out brics with new index values
print(brics)

          area    capital       country  population
    BR   8.516   Brasilia        Brazil      200.40
    RU  17.100     Moscow        Russia      143.50
    IN   3.286  New Dehli         India     1252.00
    CH   9.597    Beijing         China     1357.00
    SA   1.221   Pretoria  South Africa       52.98
# Import pandas as pd
import pandas as pd

# Import the cars.csv data: cars
cars = pd.read_csv('cars.csv')

# Print out cars
print(cars)

      Unnamed: 0  cars_per_cap        country drives_right
    0         US           809  United States         True
    1        AUS           731      Australia        False
    2        JAP           588          Japan        False
    3         IN            18          India        False
    4         RU           200         Russia         True
    5        MOR            70        Morocco         True
    6         EG            45          Egypt         True
# Import pandas and cars.csv
import pandas as pd
cars = pd.read_csv('cars.csv', index_col = 0)

# Print out country column as Pandas Series
print(cars['cars_per_cap'])

# Print out country column as Pandas DataFrame
print(cars[['cars_per_cap']])

# Print out DataFrame with country and drives_right columns
print(cars[['cars_per_cap', 'country']])

    US     809
    AUS    731
    JAP    588
    IN      18
    RU     200
    MOR     70
    EG      45
    Name: cars_per_cap, dtype: int64
         cars_per_cap
    US            809
    AUS           731
    JAP           588
    IN             18
    RU            200
    MOR            70
    EG             45
         cars_per_cap        country
    US            809  United States
    AUS           731      Australia
    JAP           588          Japan
    IN             18          India
    RU            200         Russia
    MOR            70        Morocco
    EG             45          Egypt
# Import cars data
import pandas as pd
cars = pd.read_csv('cars.csv', index_col = 0)

# Print out first 4 observations
print(cars[0:4])

# Print out fifth, sixth, and seventh observation
print(cars[4:6])

         cars_per_cap        country drives_right
    US            809  United States         True
    AUS           731      Australia        False
    JAP           588          Japan        False
    IN             18          India        False
         cars_per_cap  country drives_right
    RU            200   Russia         True
    MOR            70  Morocco         True
# Import cars data
import pandas as pd
cars = pd.read_csv('cars.csv', index_col = 0)

# Print out observation for Japan
print(cars.iloc[2])

# Print out observations for Australia and Egypt
print(cars.loc[['AUS', 'EG']])

    cars_per_cap      588
    country         Japan
    drives_right    False
    Name: JAP, dtype: object
         cars_per_cap    country drives_right
    AUS           731  Australia        False
    EG             45      Egypt         True
group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--verbose", action="store_true") group.add_argument("-q", "--quiet", action="store_true")


作者:yarving
链接:http://www.jianshu.com/p/fef2d215b91d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/CGAlpha/p/7814808.html