Python2.X 学习笔记

本文深入探讨了Python编程中的各种实用技巧,包括变量命名规范、代码执行时机控制、字符串处理方法、异常处理机制、装饰器的使用、生成器的功能、类的属性与方法管理等内容,适合各水平的Python开发者学习。

1. 下划线命名的特殊用法

  • _xxx 不用from module import *导入

  • __xxx__ 系统定义的名字

  • __xxx 类中的私有变量

2. 没有缩进的代码,在模块被导入的时候就会被执行。功能代码应该封装在函数或类中

  • 如果模块被导入__name__是模块的名字

  • 如果模块是直接执行的,__name__的值就是__main__

3. os.linesep需要查找两步:

  • 查找os模块

  • 在os模块中查找linesep

频繁使用这种属性的话,就定义一个本地变量ls=os.linesep.首先查找本地变量,然后再查找全局变量,最后查找内建变量,这样的话,会使程序更快

4. 对象有三部分:id()返回id,type()返回类型,还有值。id(),type()返回的也是对象。

5. None。空对象不是Null,注意!

6. xrange()可以节省内存,或range()无法完成的超大数据的场合

7. 整形和字符串,python会做缓存,所以a=1,b=1, a==b结果是true

8. 转换字符串:

  • repr()返回字符串对Python友好,通常obj == eval(repr(obj)),但不总成立

  • str()对用户友好,返回结果通常无法用eval()求值。

9. float不精确,精确数字用decimal模块的Decimal类型

10. 字符串不可变。x=’aa’.id(x);x=’bb’;id(x);可以看到id是不同的,虽然引用名是一个。

11. 复数:xxx+xxxJ,例如:54.sdf+1.5J

12. from __future__ import division,后,1/2 (真正除)结果为0.5 ,  1//2 (地板除)结果为 0

13. ord(‘a’) 是97,chr(97)是 a

14. print r’\n’的结果是\n。如果前面不加r,结果则是换行。R是取消转义

15. 浅拷贝只是把对象重新赋一个引用,深拷贝(copy.deepcopy())复制一份对象。但是对原子类型(不可变类型:数字,字符串,代码,类型,xrange,元组等),深拷贝不会执行,或者说执行的效果和浅拷贝是一样的

16. 可变集合set,不可变集合frozenset

17. 没有switch语句

18. 三元表达式:X if C else Y.如:

smaller = x if x<y else y.

19. else 可以写在while或for后面,循环结束后会执行else的内容。break会跳过else中的内容

20. pass语句就是什么也不做。代替分号空语句,或{}空语句的实现

21. 列表解析:[expr for iter_var in iterable if cond_expr]如:

[x**2 for x in range(10) if x%2==0].

注意两边的中括号.if 部分可以省略。不加if想到于map(),加if相当于filter()。

另可以:    

1. [(x+1,y+1) for x in range(3) for y in range(5)]
2.  f = open(“x.txt”,’r’)
    len([word for line in f for word in line.split()])

22. 列表解析的一个不足是必须生成所有的数据,用以创建整个列表。对大量数据的迭代器有负面效应。生成器表达式结合列表解析和生成器解决了这个问题。

生成器表达式:(expr for iter_var in iterable if cond_expr),和列表解析只有外面的括号不同

23. read不会自动去除分隔符,write不会自动写入分隔符。需要手动去除或写入。所以也没有writeline()方法。例如:f.write(‘%s%s’ %(aline, os.linesep) )

24. 读文件的时候,如果要使用print,要在print后面加逗号。因为print默认会有一个换行符,而读文件readline()和readlines()对文件中的换行符不会做处理,所以如果不加逗号的话,会有两个换行符打印出来。正确的写法应该类似这样:

f = open(“c:\pmpadmin”)
for line in f:
 print line,

25. 引用sys模块。sys.stdin,sys.stdout,sys.stderr三种标准输入输出。这三个都是文件,要自己处理换行符。

26. sys.argv是命令行参数列表。sys.argv[0]是程序本身名称

27. except可以处理多个异常,所有的异常放在元组中。如:

except  (NameError,ValueError),reason

28. 异常树:

  • BaseException

  • KeyboardInterrupt

  • SystemExit

  • Exception

  • 其他build-in的异常

29. try:

 A
 except:
 B
 else:
 C
 finally:
 D

没有异常执行ACD,有异常执行ABD

30. 可以raise一个异常

31. 断言assert exp[, arg],可以用except捕获AssertionError和其arg原因

32. 异常信息可以通过sys.exc_info()得到。此方法返回3个元素的元组,分别是

  • exc_type:异常类

  • exc_value:异常类实例

  • exc_traceback:跟踪记录对象

33. 函数没有返回值的时候默认是返回None,返回一个时类型是Object,返回数大于1的时候,其实返回的是一个元组。

34. 调用函数时,参数可以指定,而不一定按照定义的顺序def x(x,y),可以这样调用x(y=1,x=2),会自己赋给相应的参数

35. 装饰器:

  • 无参数装饰器:

@deco
def foo():pass

等价于

foo = deco(foo)
  • 带参数装饰器:

@deco(arg)
def foo():pass

等价于

foo = (deco(arg))(foo)

,其实返回的是一个函数引用

  • 多重装饰器执行:

@x
@y
def foo():pass

    等价于

foo = x(y(foo))
  • 装饰器的例子:

def dec(f):
...  def inner():
...  print "in decorator,HAHA"
...  print '%s called' %(f.__name__)
...  return f()
...  return inner()

@dec
def haha():
...  print "haha function"

执行结果:

in decorator,HAHA
haha called
haha function

36. 传递函数:

def convert(func, seq):
 return [func(each) for each in seq]
myseq = (123,2.5,-6.2e8,999999999L)

执行转换:

convert(int, myseq)
convert(long, myseq)

37. 函数可变参数:

  • 非关键字:非关键字传的是元组

def func([formal_args,] *vargs_tuple)
  • 关键字:

def func([formal_args,][ *vargs_tuple, ] **vargsd)

    **后面是字典

38. 匿名函数lambda:

def formal(x, y=2): return x+y

    等价于

lambda x, y=2: x+y

    lambda返回一个函数句柄

39. 函数式编程内建函数:

filter(func, seq)
map(func,seq1[,seq2…])
reduce(func,seq[,int])

40. 偏函数(partial function application PFA),将任意数量(顺序)的参数的函数转化成另一个带剩余参数的函数对象。

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
  • 其实就等价于定义了一个basetwo函数:

basetwo(x) = int(x, base=2)
  • 关键字参数会自动加到后面,否则应该在后面附加x:basetwo = partial(int, 2)等价于basetwo(x) = int(2,x),就会和愿意不一致

41. 函数内的变量如果和全局变量名称一样的时候,就会在函数内覆盖掉全局变量,但是做出任何改变都不会影响原有的全局变量的值。但是可以显示的加上global关键字,表示在函数内引用这个全局变量,并且做出任何修改都会影响原有全局变量的值

42. 闭包(closure):在一个内部函数里,对外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包

43. 自由变量:定义在外部函数内的,但由内部函数引用或者使用的变量

44. 用yield关键字做“生成器”:

>>> def test():
 yield "1"
 yield 2

>>> x = test()
>>> x.next()
'1'
>>> x.next()
2

45. 当yield后面接表达式的时候,可以用send()传递一个值给生成器。

46. 用close()关闭生成器。close后调用next会抛异常

47. sys.path显示当前的lib目录。如果import失败,找不到module。可以用sys.append(“new path…(module所在的路径)”)来添加一个系统环境path,再次import就可以了

48. 推荐import顺序:

  • Python标准库模块

  • Python第三方模块

  • 应用程序自定义模块

使用空行分隔这三类

49. [from …] import … [as …]

50. globals(),locals()分别返回包含全局,局部命名空间的所有名字的字典

51. utf-8编码的源文件开头应该这样写:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

52. 实例化类不需要new关键字。

53. __init__方法在实例化类时调用,__del__方法在实例的引用计数为0的时候调用。

54. python可以在运行时添加实例属性

55. __init__应该返回None

56. 类属性

class C(object):
 version = 1.2
 x = {2:”this is 2”}
c = C()

  • 不可变类型。通过实例赋值c. version = 3的时候,类属性会被隐藏。也就是说C. version还是1.2,但是实例c. version已经是3了。通过类改变变量C. version = 3,会修改类变量的值,且对所有的实例中的变量都生效

  • 可变类型。即使通过实例来修改x的值,也会影响到所有的类实例.

57. self在类方法中其实就代表:调用该方法的实例。没有实例化是不能调用类方法的。类方法的第一个参数应该是self。self的意义类似java中的this

58. 静态方法:@staticmethod。类方法(与类相关,与实例无关):@classmethod

59. 继承:

class Sub(Parent1[, parent2,…])

60. 子类如果有__init__方法,父类__init__不会调用。和java不同

61. 调用父类方法,用super方法:

class TestClass(object):
    staticField = 1
    def __init__(self):
        print "this is in TestClass init"

class Sub(TestClass):
    def __init__(self):
        super(Sub, self).__init__()
        print "this is in Sub init"

62. hasattr(),getattr(),setattr(),delattr()操作属性。可以应用到类和实例

63. issubclass(),isinstance()

64. dir()列出所有属性,可以应用在实例,类,模块

65. 可以定义类变量__slots__,可以是列表,元组或可迭代对象。__slots__规定了类实例能拥有的属性,动态定义属性必须在slots中,否则报AttributeError异常。定义slots后,不会存在__dict__了

66. 描述符:对象代理时使用。至少实现下面3个方法:

def __get__(self,obj,typ=None)  =>  value
def __set__( self,obj,val)  => None
def __delete__(self, obj)  => None

67. __getattribute__()实现的优先级顺序

  • 类属性

  • 数据描述符

  • 实例属性

  • 非数据描述符

  • 默认为__getattr__()

68. 用property()直接定义属性的get,set,delete方法,而不用另写一个描述符类

class TestProperty(object):
    def __init__(self, x):
        self.__x = ~x
    
    #def set(self, x):
    #    print "set x"
    #    self.__x = ~x
    
    def get(self):
        print "get x"
        return ~self.__x
    
    x = property(get)

tp = TestProperty(10)
print tp.x
tp.x = 30

Traceback (innermost last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

官方例子:

class C(object):
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x
    def setx(self, value):
        self._x = value
    def delx(self):
        del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

69. 使用@property, property(fget=None,fset=None,fdel=None,doc=None):

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

70. property用法续:(@方式没成功,原因待找):

class C(object):
    def __init__(self, x):
        self.y = x

    #@property 【这里没成功,下面的y = property(**y())其实是2.4版本前的方法】
    def y():
        
        def fget(self):
            print "=== fget ==="
            return self.__x
            
            
        def fset(self, x):
            print "=== fset ==="
            self.__x = x
        
        print "y.locals()= ", locals()      
        
        return locals()
    
    y = property(**y()) 【上面@property的2.4版本前的替代写法】

c=C("CCCCCCCCCC")
c.y
c.y="xx"

71. 元类(metaclass),在类定义之前的操作。元类的实例就是其他类

class TestMetaclass(type):
    
    def __init__(cls, name, bases, attrd):
        super(TestMetaclass,  cls).__init__(name, bases, attrd)
        print "in metaclass"
        
        if '__str__' not in attrd:
            print "class requires overriding of __str__()"
        
        

print "class definition"
class ApplyMetaclass(object):
    __metaclass__ = TestMetaclass
    
    def __init__(self):
        print "in ApplyMetaclass init method"
    
print "end class definition"

a = ApplyMetaclass()

    输出:

class definition
in metaclass
class requires overriding of __str__()
end class definition
in ApplyMetaclass init method

72. 类实现__call__方法,类的实例才能成为可调用的。其实foo(arg)等价于foo.__call__(self,arg)

73. input()等价于eval(raw_input()):

list = input(":\n")
:
[1,2]
>>> list
[1, 2]
>>> type(list)
<type 'list'>

74. subprocess模块

  • 替代os.system()

import subprocess
r = subprocess.call(('dir',r'c:\windows'), shell=True)
  • 替代os.popen()

import subprocess
f = subprocess.Popen(('ls','-la'), stdout=subprocess.PIPE).stdout
data = f.readline()
f.close()

75. sys.exitfunc默认禁止,但是可以改写,在sys.exit()之前调用,进行清理工作。新写函数要判断hasattr(sys,’exitfunc’),如果原来就有,要写成新函数的一部分调用。sys.exitfunc是无参函数

76. os._exit()不进行任何清理,直接退出python


转载于:https://my.oschina.net/bigsloth/blog/192881

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值