zoukankan      html  css  js  c++  java
  • 一些代码 II (ConfigParser、创建大文件的技巧、__getattr__和__getattribute__、docstring和装饰器、抽象方法)

    1. ConfigParser

    format.conf

     1 [DEFAULT]
     2 conn_str = %(dbn)s://%(user)s:%(pw)s@%(host)s:%(port)s/%(db)s
     3 dbn = mysql
     4 user = root
     5 host = localhost
     6 port = 3306
     7 
     8 [db1]
     9 user = aaa
    10 pw = ppp
    11 db = example
    12 
    13 [db2]
    14 host = 172.16.88.1
    15 pw = www
    16 db = example

    readformatini.py

    1 import ConfigParser
    2 
    3 conf = ConfigParser.ConfigParser()
    4 conf.read('format.conf')
    5 print conf.get('db1', 'conn_str')    # mysql://aaa.ppp@localhost:3306/example
    6 print conf.get('db2', 'conn_str')    # mysql://root:www@172.16.88.1:3306/example

    get(section, option[, raw[, vars]]) 的查找规则如下:

    1)如果找不到节点名,就抛出 NoSectionError。

    2)如果给定的配置项出现在 get() 方法的 vars 参数中,则返回 vars 参数中的值。

    3)如果在指定的节点总含有给定的配置项,则返回其值。

    4)如果在 [DEFAULT] 中有指定的配置项,则返回其值。

    5)如果在构造函数的 default 参数中有指定的配置项,则返回其值。

    6)抛出 NoOptionError。

    2. 创建大文件的技巧

    1 f = open('large.csv', 'wb')
    2 f.seek(1073741824-1)    # 创建大文件的技巧
    3 f.write('')
    4 f.close()
    5 
    6 import os
    7 os.stat('large.csv').st_size # 输出文件的大小 1073741824L

    大数据的 csv 文件请使用 Pandas 来处理。

    3. __getattr__和__getattribute__

     1 # -*- coding:utf-8 -*-
     2 class A(object):
     3     _c = 'test'
     4     def __init__(self):
     5         self.x = None
     6         
     7     @property
     8     def a(self):
     9         print 'using property to acess attribute'
    10         if self.x is None:
    11             print 'return value'
    12             return 'a'
    13         else:
    14             print 'error occured'
    15             raise AttributeError
    16         
    17     @a.setter
    18     def a(self, value):
    19         self.x = value
    20         
    21     def __getattr__(self, name):
    22         print 'using __getattr__ to access attribute'
    23         print 'attribute name:', name
    24         return 'b'
    25     
    26     def __getattribute__(self, name):
    27         print 'using __getattribute__ to access attribute'
    28         return object.__getattribute__(self, name)
    29 
    30 a1 = A()
    31 print a1.a
    32 print '--------------'
    33 a1.a = 1
    34 print a1.a
    35 print '--------------'
    36 print A._c

    输出如下:

    using __getattribute__ to access attribute
    using property to acess attribute
    using __getattribute__ to access attribute
    return value
    a
    --------------
    using __getattribute__ to access attribute
    using property to acess attribute
    using __getattribute__ to access attribute
    error occured
    using __getattr__ to access attribute
    attribute name: a
    b
    --------------
    test

    当实例化 a1 时由于其默认的属性 x 为 None,当我们发你问 a1.a 时,最先搜索的是 __getattribute__() 方法,由于 a 是一个 property 对象,并不存在于 a1 的 dict 中,因此不能返回该方法,此时会搜索 property 中定义的 get() 方法,所以返回的结果是 ‘a’。当用 property 中的 set() 方法对 x 进行修改并再次访问 property 的 get() 方法时会抛出异常,这种情况下回触发对 __getattr__() 方法的调用并返回结果 ‘b’。程序最后访问类变量输出 ‘test’ 是为了说明对类变量的方位不会涉及 __getattribute__() 和 __getattr__() 方法:

    注意:__getattribute__() 总会被调用,而__getattr__() 方法仅在如下情况才会被调用:

    1)属性不在实例的 __dict__ 中;

    2)属性不在其基类以及祖先类的 __dict__ 中;

    3)触发 AttributeError 异常时(不仅仅是 __getattribute__() 引发的 AttributeError 异常,property 中定义的 get() 方法抛出异常的时候也会调用该方法)。

    4. docstring和装饰器

     1 import inspect  2 def is_admin(f):     
     3     def wrapper(*args, **kwargs):
     4         func_args = inspect.getcallargs(f, *args, **kwargs)    # func_args = {'username': '***', 'type': '***'}
     5         if func_args.get('username') != 'admin':
     6             raise Exception('This user is not allowed to get food')
     7         return f(*args, **kwargs)
     8     return wrapper
     9  
    10 def foobar(username='someone', type="chocolate"):
    11     """do crazy stuff"""
    12     pass
    13  
    14 print foobar.func_doc    # do crazy stuff
    15 print foobar.__name__    # foobar
    16 
    17 @is_admin
    18 def foobar1(username='anyone', type="chocolate"):
    19     """ do another crazy stuff"""
    20     pass
    21  
    22 print foobar1.__doc__    # None,此时的__doc__应该是wrapper的
    23 print foobar1.__name__    # wrapper

    有装饰器的函数会丢失自己的 docstring,使用 functools 中的 wraps 可保留自己的 docstring。将 is_admin() 更改如下即可:

     1 # -*- coding:utf-8 -*-
     2 import functools
     3 import inspect
     4  
     5 def check_is_admin(f):
     6     @functools.wraps(f)    # 注意这行~~~~
     7     def wrapper(*args, **kwargs):
     8         func_args = inspect.getcallargs(f, *args, **kwargs)
     9         print func_args
    10         if func_args.get('username') != 'admin':
    11             raise Exception('This user is not allowed to get food')
    12         return f(*args, **kwargs)
    13     return wrapper

    另:inspect 模块允许提取函数签名并对其进行操作。

          inspect.getcallargs() 返回一个将参数名字和值作为键值的字典。以上面例子调用 foobar('admin',"rice"),则 func_args 的值为 {'username': 'admin', 'type': 'rice'}

    5. 抽象方法

    简单的抽象方法:

    1 # -*- coding:utf-8 -*-
    2 class Pizza(object):
    3     @staticmethod
    4     def get_radius():
    5         raise NotImplementedError
    6     
    7 p = Pizza()        # 不报错
    8 p.get_radius()    # 报错

    实例化时不报错,在真正调用时才报错,报错如下:

    Traceback (most recent call last):
      File "tt.py", line 8, in <module>
        p.get_radius()
      File "tt.py", line 5, in get_radius
        raise NotImplementedError
    NotImplementedError

    使用abc实现抽象方法:

     1 # -*- coding:utf-8 -*-
     2 import abc
     3 
     4 class BasePizza(object):
     5     __metaclass__ = abc.ABCMeta    # python2的元类声明方式
     6     
     7     @abc.abstractmethod
     8     def get_radius():
     9         """Method that should do something."""
    10         pass
    11     
    12 p = BasePizza()    # 报错
    13 p.get_radius()      # 不执行

    类在实例化时就报错,报错如下:

    Traceback (most recent call last):
      File "tt.py", line 12, in <module>
        p = BasePizza()
    TypeError: Can't instantiate abstract class BasePizza with abstract methods get_radius
  • 相关阅读:
    sql一对多的两个表的update
    textArea 高度自适应
    js切换不同的div的颜色
    [Python]闭包的理解和使用
    运维面试
    [linux]ubuntu修改镜像源
    [vsftpd] ubuntu14.04 ansible剧本安装vsftpd流程及报错排查
    windows环境下使用virtualenv对python进行多版本隔离
    [python]打印异常信息的不同方式
    [python]字典的直接赋值、浅拷贝和深拷贝解析
  • 原文地址:https://www.cnblogs.com/liuq/p/5531600.html
Copyright © 2011-2022 走看看