pythonic 风格编码

入门python好博客

进阶大纲

有趣的灵魂

老齐的教程

老齐还整理了很多精华

听说 fluent python + pro python 这两本书还不错!

元组三种遍历,有点像字有四种写法一样。。。苦笑

  1. for index in range(0,len(tuple_1)):
  2. ... print(tuple_1[index])
  3. >>> for index in range(0,len(tuple_1)):
  4. ... print('{}--{}'.format(index,tuple_1[index]))
  5. >>> tuple_1 = (1,2,'hello','world')
  6. >>> for content in tuple_1:
  7. ... print(content)
  8. >>> for index,enum in enumerate(tuple_1):
  9. ... print('{}--{}'.format(index,enum))
  10. # 黑魔法咩? map ,reduce
  11. from functools import reduce
  12. def str2int(s):
  13. Digital = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
  14. return Digital[s]
  15. def str_reduce(s):
  16. l = list(map(str2int,s))
  17. if not isinstance(s, str):
  18. raise ValueError('输入不是字符串类型!')
  19. return reduce(lambda x,y:x+y,[v * 10**(len(l)-i-1) for i , v in enumerate(l)])
  20. str_reduce('213')
  21. # 更加 逆天的 map 用法,不论传入的 list 是普通值 还是 func 都行
  22. >>> for i in range(10):
  23. ... print(list(map(lambda x:x(i),[lambda x:x+x,lambda x:x**2])))
  24. # filter 用法
  25. >>> list_1 = [i for i in range(30) if i%2 == 1]
  26. >>> list_1
  27. [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]
  28. >>> list(filter(lambda x:x<10,list_1))
  29. [1, 3, 5, 7, 9]
  1. tuple 互转 tuple(list_1) , list(tuple_2)
  2. >>> import os
  3. >>> print(os.path.abspath('.'))
  4. C:\Users\FrankLi\Desktop
  5. >>> import sys
  6. >>> print(sys.argv)
  7. ['']
  8. >>> print(sys.executable)
  9. D:\Program Files (x86)\python\python.exe
  • 列表生成式 vs 生成器表达式
  1. >>> [x for x in list_1 if x%2==1]
  2. [1, 3, 5]
  3. >>> (x for x in list_1 if x%2==1)
  4. <generator object <genexpr> at 0x033C2660>
  5. >>> gen = (x for x in range(0,10) if x%3==1)
  6. >>> for x in gen:
  7. ... print(x)
  8. ...
  9. 1
  10. 4
  11. 7
  12. >>> #这是一个生成器应用,斐波拉契数列
  13. ... def fib(max):
  14. ... n,a,b=0,1,1
  15. ... while n<=max:
  16. ... yield b
  17. ... a,b=b,a+b
  18. ... n=n+1
  19. ... return 'Nore More!'
  20. ...
  21. >>> for f in fib(6):
  22. ... print('fib: {}'.format(f))
  23. ...
  24. fib: 1
  25. fib: 2
  26. fib: 3
  27. fib: 5
  28. fib: 8
  29. fib: 13
  30. fib: 21
  31. >>> def fib(x):
  32. ... a,b = 1,1
  33. ... for i in range(x):
  34. ... yield a
  35. ... a,b = b,a+b
  36. ...
  37. >>> for i in fib(10):
  38. ... print(i)
  39. ...
  40. 1
  41. 1
  42. 2
  43. 3
  44. 5
  45. 8
  46. 13
  47. 21
  48. 34
  49. 55
  50. #获取生成器重的 return 返回值 Nore More!
  51. >>> g = fib(6)
  52. >>> while True:
  53. ... try:
  54. ... x=next(g)
  55. ... print('g: {}'.format(x))
  56. ... except StopIteration as e:
  57. ... print('evalue: {}'.format(e.value))
  58. ... break
  59. ...
  60. g: 1
  61. g: 2
  62. g: 3
  63. g: 5
  64. g: 8
  65. g: 13
  66. g: 21
  67. evalue: Nore More!
  68. # string 也是序列可以被迭代 iter(s) 即可
  69. >>> s = 'google'
  70. >>> s_iter = iter(s)
  71. >>> while True:
  72. ... try:
  73. ... print(next(s_iter))
  74. ... except StopIteration as stopIter:
  75. ... print('done')
  76. ... break
  77. ...
  78. g
  79. o
  80. o
  81. g
  82. l
  83. e
  84. done
  85. >>> # 杨辉三角末尾补零两数相加大法
  86. ... def triangle():
  87. ... l=[1]
  88. ... while True:
  89. ... yield l
  90. ... l.append(0)
  91. ... l=[l[i-1]+l[i] for i in range(0,len(l))]
  92. 调用杨辉三角生成器
  93. >>> n=0
  94. >>> for e in triangle():
  95. ... n=n+1
  96. ... print(e,'\t')
  97. ... if n==10:
  98. ... break
  99. ...
  100. [1]
  101. [1, 1]
  102. [1, 2, 1]
  103. [1, 3, 3, 1]
  104. [1, 4, 6, 4, 1]
  105. [1, 5, 10, 10, 5, 1]
  106. [1, 6, 15, 20, 15, 6, 1]
  107. [1, 7, 21, 35, 35, 21, 7, 1]
  108. [1, 8, 28, 56, 70, 56, 28, 8, 1]
  109. [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

迭代器

  1. Generator 天然的 迭代器
  2. tuple , list 序列如果要编程 迭代器 需要 iter(list_1) iter(tuple_2)
  3. >>> from collections import Iterator
  4. >>> isinstance((1,2,3,4),Iterator)
  5. False
  6. >>> isinstance((x for x in range(10) if x%2==0),Iterator)
  7. True
  8. >>>
  9. >>> isinstance(iter((1,2,3,4)),Iterator)
  10. True
  11. >>>
  12. >>> list_1 = [1,2,3,4]
  13. >>> list_1_iter = iter(list_1)
  14. >>> while True:
  15. ... try:
  16. ... x=next(list_1_iter)
  17. ... print('x:{}'.format(x))
  18. ... except StopIteration as e:
  19. ... print('e.value: {}'.format(e.value))
  20. ... break
  21. ...
  22. x:1
  23. x:2
  24. x:3
  25. x:4
  26. e.value: None
  • python map reduce 实现
  1. >>> def pow2(val):
  2. ... return val**2
  3. ...
  4. >>> list_1 = [1,2,3,4,5]
  5. >>> list(map(pow2,list_1))
  6. [1, 4, 9, 16, 25]
  7. >>> def sum(x,y):
  8. ... return x+y
  9. ...
  10. >>> from functools import reduce
  11. >>> reduce(sum,list(map(pow2,list_1)))
  12. 55
  13. 强悍的 lambda
  14. >>> from functools import reduce
  15. >>> reduce(lambda x,y:x+y,list(map(lambda x:x**2,[1,2,3,4,5,6,7])))
  • 注意区别 Iterable 可迭代 与 Iterator 惰性迭代器

高阶函数

  1. >>> def lazy_sum(*args):
  2. ... def sum():
  3. ... ax=0
  4. ... for n in args:
  5. ... ax=ax+n
  6. ... return ax
  7. ... return sum
  8. ...
  9. >>> lazy_sum(1,2,3,4,5)
  10. <function lazy_sum.<locals>.sum at 0x013902B8>
  11. >>> f=lazy_sum(1,2,3,4,5)
  12. >>> f()
  13. 15

win 下 python 清屏

  1. >>> import os
  2. >>> def clear():
  3. ... os.system('cls')
  4. >>> import os
  5. >>> def cls():
  6. ... if os.name.upper() == 'NT':
  7. ... os.system('cls')
  8. ... else:
  9. ... os.system('clear')

可变参数,巧调用

python的可变参数和关键字参数(*args **kw)

讲*args 可变参数, **kw 关键字参数非常好的文章

  1. >>> def test(*args):
  2. ... sum=0
  3. ... for n in args:
  4. ... sum=sum+n
  5. ... return sum
  6. ... test([1,2,3,4])
  7. File "<stdin>", line 6
  8. test([1,2,3,4])
  9. ^
  10. SyntaxError: invalid syntax
  11. >>> test(*[1,2,3,4])
  12. 10
  13. >>> test(1,2,3,4)
  14. 10
  15. python3 中已经废除了 dict has_key 方法 key in dict 这种方式代替
  16. >>> def person(*args,**kw):
  17. ... l=[]
  18. ... for n in args:
  19. ... l.append(n)
  20. ... dic=kw
  21. ... if 'city' in dic:
  22. ... pass
  23. ... if 'job' in dic:
  24. ... pass
  25. ... print('l:{} dic {}'.format(l,dic))
  26. ...
  27. >>> person('tom',2,city='changsha',job='unknown')
  28. l:['tom', 2] dic {'city': 'changsha', 'job': 'unknown'}
  29. 进阶
  30. >>> extra = {'city':'cs','job':'developer'}
  31. >>> tuple=('tom',30)
  32. >>> person(*tuple,**extra)
  33. l:['tom', 30] dic {'city': 'cs', 'job': 'developer'}
  34. >>>

装饰器类似于 java 里的 AOP 动态代理,或者继承组合

  1. >>> import functools
  2. >>> #自定义文本消息的事务装饰器
  3. ... def trans(text):
  4. ... def decorater(func):
  5. ... @functools.wraps(func)
  6. ... def wrapper(*args,**kw):
  7. ... print('{} {}'.format(text,func.__name__))
  8. ... return func(*args,**kw)
  9. ... return wrapper
  10. ... return decorater
  11. ...
  12. >>> @trans('开启事务'):
  13. File "<stdin>", line 1
  14. @trans('开启事务'):
  15. ^
  16. SyntaxError: invalid syntax
  17. >>> @trans('开启事务')
  18. ... def trans_func():
  19. ... print('我是一个要被事务装饰的函数')
  20. ...
  21. >>> trans_func()
  22. 开启事务 trans_func
  23. 我是一个要被事务装饰的函数
  24. >>> from functools import wraps
  25. >>> def my_decorator(func):
  26. ... @wraps(func)
  27. ... def wrap_func():
  28. ... print('before...')
  29. ... func()
  30. ... print('after...')
  31. ... return wrap_func
  32. ...
  33. >>> @my_decorator
  34. ... def func_a():
  35. ... print('func_a...')
  36. ...
  37. >>> func_a()
  38. before...
  39. func_a...
  40. after...
  41. >>> func_a.__name__
  42. 'func_a'
  43. >>> from functools import wraps
  44. >>> def custom_text(text):
  45. ... def decorater(func):
  46. ... @wraps(func)
  47. ... def wrap_decorated(*args,**kwargs):
  48. ... print('{} {}'.format(text,func.__name__))
  49. ... return func(*args,**kwargs)
  50. ... return wrap_decorated
  51. ... return decorater
  52. ...
  53. >>> @custom_text('自定义文本信息...')
  54. ... def tran(*args,**kwargs):
  55. ... for i in args:
  56. ... print(i,end=',')
  57. ... for key,value in kwargs.items():
  58. ... print('{}-->{}'.format(key,value))
  59. ... print('事务...社会...')
  60. ...
  61. >>> args = (1,'abc',3)
  62. >>> from functools import wraps
  63. >>> kwargs = dict(name='Frank',age=18)
  64. >>> tran(*args,**kwargs)
  65. 自定义文本信息... tran
  66. 1,abc,3,name-->Frank
  67. age-->18
  68. 事务...社会...
  69. from functools import wraps
  70. class LogIt(object):
  71. def __init__(self,log_file='out.log'):
  72. self._log_file = log_file
  73. @property
  74. def log_file(self):
  75. return self._log_file
  76. @log_file.setter
  77. def log_file(self,log_file):
  78. self._log_file = log_file
  79. def __call__(self,func):
  80. @wraps(func)
  81. def wrap_func(*args,**kwargs):
  82. log_string = '{} {}'.format(func.__name__,'called...')
  83. print('wrap_func logging...{}'+log_string)
  84. with open(self.log_file,'a') as logfile:
  85. logfile.write(log_string+'\n')
  86. self.notify(log_string)
  87. return func(*args,**kwargs)
  88. return wrap_func
  89. def notify(self,log_string):
  90. print('notify logging...{}'.format(log_string))
  91. @LogIt('out1.log')
  92. def trans(*args,**kwargs):
  93. for i in args:
  94. print(i,end=',')
  95. for key,value in kwargs.items():
  96. pritn('{}<-->{}'.format(key,value))
  97. args = ('trans start..',1,2,'test')
  98. kwargs = dict(name='Frank',age=18)
  99. trans(*args,*kwargs)
  100. wrap_func logging...{}trans called...
  101. notify logging...trans called...
  102. trans start..,1,2,test,name,age,

偏函数,可以见 functools 多么强大值得好好学学

  1. >>> convert_int_from_8 = functools.partial(int,base=8)
  2. >>> convert_int_from_8(12345)
  3. Traceback (most recent call last):
  4. File "<stdin>", line 1, in <module>
  5. TypeError: int() can't convert non-string with explicit base
  6. >>> convert_int_from_8('12345')
  7. 5349
  8. # kw 这种 dict 传值也是可以的
  9. >>> kw = {'base':8}
  10. >>> convert_int_from_8 = functools.partial(int,base)
  11. Traceback (most recent call last):
  12. File "<stdin>", line 1, in <module>
  13. NameError: name 'base' is not defined
  14. >>> convert_int_from_8 = functools.partial(int,**kw)
  15. >>> convert_int_from_8('123456')
  16. 最后,创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数,当传入:
  17. int2 = functools.partial(int, base=2)
  18. 实际上固定了int()函数的关键字参数base,也就是:
  19. int2('10010')
  20. 相当于:
  21. kw = { 'base': 2 }
  22. int('10010', **kw)
  23. 当传入:
  24. max2 = functools.partial(max, 10)
  25. 实际上会把10作为*args的一部分自动加到左边,也就是:
  26. max2(5, 6, 7)
  27. 相当于:
  28. args = (10, 5, 6, 7)
  29. max(*args)
  30. 结果为10。
  31. # 总结 就是 偏函数 其实就是把原本参数很多的函数简化参数,便于使用
  32. #当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单

模块

  1. # -*- coding: utf-8 -*-
  2. 'test module'
  3. __author__ = 'Frank Li'
  4. import sys
  5. def test():
  6. args=sys.argv
  7. if len(args)==1:
  8. print('hello world!')
  9. elif len(args)==2:
  10. print('hello {}'.format(args[1]))
  11. else:
  12. print('to many args!')
  13. if __name__ == '__main__':
  14. test()

模块搜索路径

  1. 默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:
  2. >>> import sys
  3. >>> sys.path
  4. ['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', ..., '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
  5. 如果我们要添加自己的搜索目录,有两种方法:
  6. 一是直接修改sys.path,添加要搜索的目录:
  7. >>> import sys
  8. >>> sys.path.append('/Users/michael/my_py_scripts')
  9. 这种方法是在运行时修改,运行结束后失效。
  10. 第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。

面向对象

  1. >>> class Test(object):
  2. ... def __init__(self,*args):
  3. ... self.name,self.age=args[0],args[1]
  4. ...
  5. >>> t = Test('frank',18)
  6. >>> t
  7. <__main__.Test object at 0x02F00AB0>
  8. >>> t.name
  9. 'frank'
  10. >>> t.age
  11. 18

再进一阶

  1. >>> class Person(object):
  2. ... def __init__(self,name,age,*args,**kw):
  3. ... self.name,self.age = name,age
  4. ... for arg in args:
  5. ... print('arg: {}'.format(arg))
  6. ... for key in kw:
  7. ... print('key: {}--> value: {}'.format(key,kw[key]))
  8. ...
  9. >>> args=('a',1,2,'b')
  10. >>> kw ={'city':'changsha','job':'developer'}
  11. >>> Person('frank',18,*args,**kw)
  12. arg: a
  13. arg: 1
  14. arg: 2
  15. arg: b
  16. key: city--> value: changsha
  17. key: job--> value: developer
  18. <__main__.Person object at 0x02F00DD0>
  19. >>> class Student(object):
  20. ... def __init__(self,name,score,*args,**kw):
  21. ... self.name,self.score = name,score
  22. ... for arg in args:
  23. ... print('arg: {}'.format(arg))
  24. ... for key in kw:
  25. ... if key=='city':
  26. ... self.city =kw[key]
  27. ... elif key=='job':
  28. ... self.job=kw[key]
  29. ... else:
  30. ... pring('key: {} --> value: {}'.format(key,kw[key]))
  31. ... def get_grade(self):
  32. ... if self.score >= 90:
  33. ... return '优'
  34. ... if 70<self.score<90:
  35. ... return '良'
  36. ... elif 60<self.score<=70:
  37. ... return '几个'
  38. ... else:
  39. ... return '不及格'
  40. >>> student = Student('frank',80,*args,**kw)
  41. arg: a
  42. arg: 1
  43. arg: 2
  44. arg: 3
  45. arg: c
  46. arg: d
  47. >>> student.city
  48. 'changsha'
  49. >>> student.get_grade()
  50. '良'
  51. >>>
  52. 区别于 java 这种静态语言 , python 是动态语言
  53. 小结
  54. 类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
  55. 方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
  56. 通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
  57. 和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
  58. >>> bart = Student('Bart Simpson', 59)
  59. >>> lisa = Student('Lisa Simpson', 87)
  60. >>> bart.age = 8
  61. >>> bart.age
  62. 8
  63. >>> lisa.age
  64. Traceback (most recent call last):
  65. File "<stdin>", line 1, in <module>
  66. AttributeError: 'Student' object has no attribute 'age'

访问权限控制

  1. 此方法不推荐, 应该用 set_gender() 而不是 bart._Student__gender 这种方式修改 gender 属性
  2. >>> class Student(object):
  3. ... def __init__(self,name,gender):
  4. ... self.name=name
  5. ... self.__gender=gender
  6. ... def get_gender(self):
  7. ... return self.__gender
  8. ...
  9. >>> bart = Student('Bart', 'male')
  10. >>> if bart.get_gender() != 'male':
  11. ... print('测试失败!')
  12. ... else:
  13. ... bart._Student__gender='female'
  14. ... if bart.get_gender() != 'female':
  15. ... print('测试失败!')
  16. ... else:
  17. ... print('测试成功!')
  18. ...
  19. 测试成功!
  20. 正确做法:
  21. >>> class Student(object):
  22. ... def __init__(self,name,gender):
  23. ... self.name,self.__gender=name,gender
  24. ... def set_gender(self,gender):
  25. ... self.__gender = gender
  26. ... def get_gender(self):
  27. ... return self.__gender
  28. # 测试
  29. >>> bart = Student('Bart','male')
  30. >>> if bart.get_gender() != 'male':
  31. ... print('测试失败~!')
  32. ... else:
  33. ... bart.set_gender('female')
  34. ... if bart.get_gender() != 'female':
  35. ... print('测试失败!')
  36. ... else:
  37. ... print('测试成功~!')
  38. ...
  39. 测试成功~!

以为是多态,然而是多态,更不止是多态, 只要有 run 方法的 对象 都可以 往里丢 ,这一点注意区分 java 的 接口以及父类

  1. >>> class Animal(object):
  2. ... def run(self):
  3. ... print('animal is running...')
  4. ...
  5. >>> class Dog(Animal):
  6. ... def run(self):
  7. ... print('dog is running...')
  8. ...
  9. >>> def run_twice(animal):
  10. ... animal.run()
  11. ... animal.run()
  12. ...
  13. >>> run_twice(Animal())
  14. animal is running...
  15. animal is running...
  16. >>> run_twice(Dog())
  17. dog is running...
  18. dog is running...
  19. # 逝者如斯,东流不回 ,水不继承自 Animal 类 依旧可以 往 run_twice 这个方法里丢, 在 java 里是编译错误!!!
  20. >>> class water(object):
  21. ... def run(self):
  22. ... print('water is running....and never back...')
  23. ...
  24. >>> run_twice(water())
  25. water is running....and never back...
  26. water is running....and never back...

类型判断 type vs isinstance ==》 isinstance 胜 !!! 总是优先使用 isinstance 判断

  1. >>> type(123) == int
  2. True
  3. >>> isinstance(123,int)
  4. True
  5. 下面这种判断太过于复杂
  6. 判断基本数据类型可以直接写intstr等,但如果要判断一个对象是否是函数怎么办?可以使用types模块中定义的常量:
  7. >>> import types
  8. >>> def fn():
  9. ... pass
  10. ...
  11. >>> type(fn)==types.FunctionType
  12. True
  13. >>> type(abs)==types.BuiltinFunctionType
  14. True
  15. >>> type(lambda x: x)==types.LambdaType
  16. True
  17. >>> type((x for x in range(10)))==types.GeneratorType
  18. True
  19. 并且还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple
  20. >>> isinstance([1, 2, 3], (list, tuple))
  21. True
  22. >>> isinstance((1, 2, 3), (list, tuple))
  23. True
  24. 总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。
  25. # dir 查看,然后等价
  26. >>> len('ABC') 3 >>> dir('ABC') ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
  27. # 创建自己的 len 方法, 自己写一个 __len__() 方法就是了
  28. >>> class myStr():
  29. ... def __init__(self,val):
  30. ... self.__val = val
  31. ... def __len__(self):
  32. ... return len(self.__val)
  33. ...
  34. >>> myStr('abc')
  35. <__main__.myStr object at 0x02F363D0>
  36. >>> len(myStr('abc'))
  37. 3
  38. >>>
  39. # 查看 python 内建函数
  40. >>> dir(__builtins__)
  41. ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
  42. # 查看一波
  43. >>> 'hasattr' in dir(__builtins__)
  44. True
  45. >>> 'getattr' in dir(__builtins__)
  46. True
  47. >>>
  48. 小结
  49. 通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息。如果可以直接写:
  50. sum = obj.x + obj.y
  51. 就不要写:
  52. sum = getattr(obj, 'x') + getattr(obj, 'y')
  53. 一个正确的用法的例子如下:
  54. def readImage(fp):
  55. if hasattr(fp, 'read'):
  56. return readData(fp)
  57. return None
  58. 假设我们希望从文件流fp中读取图像,我们首先要判断该fp对象是否存在read方法,如果存在,则该对象是一个流,如果不存在,则无法读取。hasattr()就派上了用场。
  59. 请注意,在Python这类动态语言中,根据鸭子类型,有read()方法,不代表该fp对象就是一个文件流,它也可能是网络流,也可能是内存中的一个字节流,但只要read()方法返回的是有效的图像数据,就不影响读取图像的功能。

getter setter

  1. >>> class Student(object):
  2. ... def __init__(self,name,*args,**kw):
  3. ... self.__name = name
  4. ... for arg in args:
  5. ... print('arg: {}'.format(arg))
  6. ... for key in kw:
  7. ... if key == 'city':
  8. ... print('city %s' %kw[key])
  9. ... @property
  10. ... def score(self):
  11. ... return self._score
  12. ... @score.setter
  13. ... def score(self,value):
  14. ... self._score = value
  15. ...
  16. >>> s = Student()
  17. Traceback (most recent call last):
  18. File "<stdin>", line 1, in <module>
  19. TypeError: __init__() missing 1 required positional argument: 'name'
  20. >>> s = Student('frank',*(1,2,'a',3),**{'city':'changsha','job':'unknown'})
  21. arg: 1
  22. arg: 2
  23. arg: a
  24. arg: 3
  25. city changsha
  26. >>> s.score = 80
  27. >>> s.score
  28. 80
  29. >>> class Screen(object):
  30. ... @property
  31. ... def width(self):
  32. ... return self._width
  33. ... @width.setter
  34. ... def width(self,width):
  35. ... self._width = width
  36. ... @property
  37. ... def height(self):
  38. ... return self._height
  39. ... @height.setter
  40. ... def height(self,height):
  41. ... self._height = height
  42. ... @property
  43. ... def resolution(self):
  44. ... self._resolution = self._width * self._height
  45. ... return self._resolution
  46. ...
  47. >>> s = Screen()
  48. >>> s.width = 600
  49. >>> s.height = 800
  50. >>> s.resolution
  51. 480000

记住标准写法就好,别追问,会晕!!!

  1. >>> class Student(object):
  2. ... def __init__(self,name,score,*args,**kw):
  3. ... self._name = name
  4. ... self._score = score
  5. ... if len(args)!=0:
  6. ... self.arg = args[0]
  7. ... for key in kw:
  8. ... if key == 'city':
  9. ... self.city = kw[key]
  10. ... @property
  11. ... def name(self):
  12. ... return self._name
  13. ... @name.setter
  14. ... def name(self,name):
  15. ... self._name = name
  16. ... @property
  17. ... def score(self):
  18. ... return self._score
  19. ... @score.setter
  20. ... def score(self,score):
  21. ... self._score = score
  22. ...
  23. >>> args=('a',1,2)
  24. >>> kw = {'city':'changsha','job':'unknown'}
  25. >>> s = Student('frank',100,*args,**kw)
  26. >>> s.name
  27. 'frank'
  28. >>> s.score
  29. 100
  30. >>> s.city
  31. 'changsha'
  32. >>> s.arg
  33. 'a'
  34. >>> class Student(object):
  35. ... def __init__(self,name,age,score,*args,**kw):
  36. ... self._name=name
  37. ... self._age = age
  38. ... self._score = score
  39. ... if len(args)!=0:
  40. ... self.arg = args[0]
  41. ... for key in kw:
  42. ... if key == 'city':
  43. ... self.city = kw[key]
  44. ... @property
  45. ... def name(self):
  46. ... return self._name
  47. ... @name.setter
  48. ... def name(self,name):
  49. ... self._name = name
  50. ... @property
  51. ... def age(self):
  52. ... return self._age
  53. ... @age.setter
  54. ... def age(self,age):
  55. ... if not isinstance(age,int):
  56. ... raise TypeError('年龄必须为整数!')
  57. ... else:
  58. ... self._age = age
  59. ... @property
  60. ... def score(self):
  61. ... return self._score
  62. ... @score.setter
  63. ... def score(self,score):
  64. ... if not isinstance(score,int):
  65. ... raise TypeError('分数应该为整数!')
  66. ... elif not 0<= score <= 100:
  67. ... raise ValueError('分数必须介于0-100之间!')
  68. ... else:
  69. ... self._score = score
  70. ...
  71. >>> s = Student('frank',18,100)
  72. >>> s.name
  73. 'frank'
  74. >>> s.age
  75. 18
  76. >>> s.score
  77. 100

多继承 ,对应 java extends class implements Runnable 这种写法, 只是 python 木有 接口一说 貌似,我也不确定哈,自己去查查吧

  1. >>> class Animal():
  2. ... pass
  3. ...
  4. >>> Animal()
  5. <__main__.Animal object at 0x008DCF30>
  6. >>> class Mammal(Animal):
  7. ... pass
  8. ...
  9. >>> class Runnable(object):
  10. ... def run(self):
  11. ... print('running......')
  12. ...
  13. >>> class Flyable(object):
  14. ... def fly(self):
  15. ... print('flying......')
  16. ...
  17. >>> class Dog(Mammal,Runnable):
  18. ... pass
  19. ...
  20. >>> d = Dog()
  21. >>> d.run()
  22. running......
  23. >>> class Bat(Mammal,Flyable):
  24. ... pass
  25. ...
  26. ...
  27. >>> b = Bat()
  28. >>> b.fly()
  29. flying......

定制类

  1. # __slot__ 固定 self 属性个数
  2. # __str__ 区别 于 __repr__ 前一个 是 返回给 用户的 , 第二个 是 返回给 程序员 用来调试的
  3. >>> class Student(object):
  4. ... def __init__(self,name):
  5. ... self.name = name
  6. ... def __str__(self):
  7. ... return 'Student object (name = {})'.format(self.name)
  8. ... __repr__ = __str__
  9. ...
  10. >>> s = Student('frank')
  11. >>> s
  12. Student object (name = frank)

枚举类

  1. >>> from enum import Enum
  2. >>> Month = Enum('Month',('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
  3. >>> for name,member in Month.__members__.items():
  4. ... print(name, '=>', member, ',', member.value)
  5. ...
  6. Jan => Month.Jan , 1
  7. Feb => Month.Feb , 2
  8. Mar => Month.Mar , 3
  9. Apr => Month.Apr , 4
  10. May => Month.May , 5
  11. Jun => Month.Jun , 6
  12. Jul => Month.Jul , 7
  13. Aug => Month.Aug , 8
  14. Sep => Month.Sep , 9
  15. Oct => Month.Oct , 10
  16. Nov => Month.Nov , 11
  17. Dec => Month.Dec , 12
  18. >>> from enum import Enum,unique
  19. >>> @unique
  20. ... class Weekday(Enum):
  21. ... Sun=0
  22. ... Mon=1
  23. ... Tue=2
  24. ... Wed=3
  25. ... Thu=4
  26. ... Fri=5
  27. ... Sat =6
  28. ...
  29. >>> day1 = Weekday.Sun
  30. >>> day1
  31. <Weekday.Sun: 0>
  32. >>> day1.value
  33. 0
  34. >>> day1 = Weekday(0)
  35. >>> day1
  36. <Weekday.Sun: 0>
  37. >>> day1.value
  38. 0
  39. >>> for name,member in Weekday.__members__.items():
  40. ... print(name,'==>',member)
  41. ...
  42. Sun ==> Weekday.Sun
  43. Mon ==> Weekday.Mon
  44. Tue ==> Weekday.Tue
  45. Wed ==> Weekday.Wed
  46. Thu ==> Weekday.Thu
  47. Fri ==> Weekday.Fri
  48. Sat ==> Weekday.Sat

枚举类与错误综合小例子

  1. >>> class Student(object):
  2. ... def __init__(self,name,gender):
  3. ... if not isinstance(gender,Gender):
  4. ... raise TypeError('{}'.format('传入的性别类型异常'))
  5. ... self.__name = name
  6. ... self.gender = gender
  7. ...
  8. >>> bart = Student('Bart', Gender.Male)
  9. >>> if bart.gender == Gender.Male:
  10. ... print('测试通过!')
  11. ... else:
  12. ... print('测试失败!')
  13. ...
  14. 测试通过!
  15. >>> bart = Student('Bart', '男')
  16. Traceback (most recent call last):
  17. File "<stdin>", line 1, in <module>
  18. File "<stdin>", line 4, in __init__
  19. TypeError: 传入的性别类型异常
  20. >>>

元类,我服了!!!

推荐一篇高分文章读懂元类

  1. >>> def fn(self,world = 'world!'):
  2. ... print('hello {}'.format(world))
  3. ...
  4. >>> Hello = type('Hello',(object,),dict(hello = fn))
  5. >>> h = Hello()
  6. >>> h.hello()
  7. hello world!
  8. >>> class ListMetaclass(type):
  9. ... def __new__(cls,name,bases,attrs):
  10. ... attrs['add']=lambda self,value:self.append(value)
  11. ... return type.__new__(cls,name,bases,attrs)
  12. ...
  13. >>> class MyList(list,metaclass=ListMetaclass):
  14. ... pass
  15. ...
  16. >>> l = MyList()
  17. >>> l.add(5)
  18. >>> l
  19. [5]
  20. # 类是一种特殊的对象,因为python 是动态语言,可以后期绑定属性方法等
  21. >>> class ObjectCreator():
  22. ... pass
  23. ...
  24. >>> print(ObjectCreator)
  25. <class '__main__.ObjectCreator'>
  26. >>> print(hasattr(ObjectCreator,'new_attribute'))
  27. False
  28. >>> ObjectCreator.new_attribute = 'foo'
  29. >>> print(hasattr(ObjectCreator,'new_attribute'))
  30. True
  31. >>> ObjectCreatorMirror = ObjectCreator
  32. >>> print(ObjectCreatorMirror())
  33. <__main__.ObjectCreator object at 0x00859A30>

异常处理

  1. >>> def div(a,b):
  2. ... if not isinstance(a,int) or not isinstance(b,int):
  3. ... raise TypeError('本方法中除数与被除数都要为整数!')
  4. ... try:
  5. ... r = a/b
  6. ... print('r: {}'.format(r))
  7. ... except ZeroDivisionError as e:
  8. ... print('except: ',e)
  9. ... finally:
  10. ... print('finally...')
  11. ... print('END...')
  12. >>> r = div(1,2)
  13. r: 0.5
  14. finally...
  15. END...
  16. >>> div(1,0)
  17. except: division by zero
  18. finally...
  19. END...
  20. >>> def foo(i):
  21. ... return 10/i
  22. ...
  23. >>> def bar(j):
  24. ... return foo(j) *2
  25. >>> def main(n):
  26. ... try:
  27. ... bar(n)
  28. ... except ZeroDivisionError as e:
  29. ... logging.exception(e)
  30. ... finally:
  31. ... print('end...')
  32. ...
  33. >>> main(5)
  34. end...
  35. >>> main(0)
  36. ERROR:root:division by zero
  37. Traceback (most recent call last):
  38. File "<stdin>", line 3, in main
  39. File "<stdin>", line 2, in bar
  40. File "<stdin>", line 2, in foo
  41. ZeroDivisionError: division by zero
  42. end...
  43. 改错:
  44. from functools import reduce
  45. def str2num(s):
  46. try:
  47. r = int(s)
  48. except ValueError as e:
  49. if isinstance(s,str):
  50. s=s.replace('.','')
  51. r = int(s)
  52. else:
  53. raise ValueError('传入的不是字符串!')
  54. finally:
  55. pass
  56. return int(s)
  57. def calc(exp):
  58. ss = exp.split('+')
  59. ns = map(str2num, ss)
  60. return reduce(lambda acc, x: acc + x, ns)
  61. def main():
  62. r = calc('100 + 200 + 345')
  63. print('100 + 200 + 345 =', r)
  64. r = calc('99 + 88 + 7.6')
  65. print('99 + 88 + 7.6 =', r)
  66. main()

既然如此重要,再谈元类

  1. # 定义一个函数,用来待会儿在 类 内部或绑定,或调用
  2. def print_s(s):
  3. print(s)
  4. # 定义元类, 必须继承自 type 才可以被当做元类,被反射
  5. class ObjectCreatorMetaClass(type):
  6. def __new__(current_class_name,class_tobe_created_name,base_classess_name_tuple,attrs_hold_dict):
  7. # 打印一波传进来的参数会发现基本跟命名一致
  8. print_s('current_class_name: {}'.format(current_class_name))
  9. print_s('class_tobe_created_name: {}'.format(class_tobe_created_name))
  10. print_s('base_classess_name_tuple: {}'.format(base_classess_name_tuple))
  11. print_s('attrs_hold_dict: {}'.format(attrs_hold_dict))
  12. #为要被创建的类 ObjectCreator 添加方法,属性都可以
  13. attrs_hold_dict['flag'] = True
  14. attrs_hold_dict['current_class_name_print'] = print_s(current_class_name)
  15. attrs_hold_dict['class_tobe_created_name_print'] = print_s(class_tobe_created_name)
  16. attrs_hold_dict['base_classess_name_tuple_print'] = print_s(base_classess_name_tuple)
  17. attrs_hold_dict['attrs_hold_dict_print'] = print_s(attrs_hold_dict)
  18. return type.__new__(current_class_name,class_tobe_created_name,base_classess_name_tuple,attrs_hold_dict)
  19. # 定义我们要被创建的 类,为了方便查看传进去的 base_classess_name_tuple ,我们手动让他继承一下 object
  20. class ObjectCreator(object,metaclass = ObjectCreatorMetaClass):
  21. pass
  22. # 思考为什么 第一次打印时候 attrs_hold_dict 会比后一次 打印 少掉一部分属性,方法 (如 'current_class_name_print': None, 'flag': True)
  23. # 因为这在传进来时候并没有绑定这些参数方法啊,是后面代码 手动绑定的啦 哈哈哈哈或或或
  24. # 上面的理解有点偏差,但愿看到的人能够自己找出,下面是我重新理解的
  25. # 定义一个函数,用来待会儿在 类 内部或绑定,或调用
  26. def print_s(s):
  27. print(s)
  28. return s
  29. #必须继承自 type 才可以被当做元类,被反射
  30. class ObjectCreatorMetaClass(type):
  31. def __new__(current_class_name,class_tobe_created_name,base_classess_name_tuple,attrs_hold_dict):
  32. # 打印一波传进来的参数会发现基本跟命名一致
  33. print_s('current_class_name: {}'.format(current_class_name))
  34. print_s('class_tobe_created_name: {}'.format(class_tobe_created_name))
  35. print_s('base_classess_name_tuple: {}'.format(base_classess_name_tuple))
  36. print_s('attrs_hold_dict: {}'.format(attrs_hold_dict))
  37. #为要被创建的类 ObjectCreator 添加方法,属性都可以
  38. attrs_hold_dict['flag'] = True
  39. attrs_hold_dict['get_metaclass'] = print_s(current_class_name)
  40. attrs_hold_dict['get_tobe_created_class'] = print_s(class_tobe_created_name)
  41. attrs_hold_dict['get_bases_classess_tuple'] = print_s(base_classess_name_tuple)
  42. attrs_hold_dict['get_attrs_hold_dict'] = print_s(attrs_hold_dict)
  43. return type.__new__(current_class_name,class_tobe_created_name,base_classess_name_tuple,attrs_hold_dict)
  44. class ObjectCreator(object,metaclass = ObjectCreatorMetaClass):
  45. pass
  46. # 思考为什么 第一次打印时候 attrs_hold_dict 会比后一次 打印 少掉一部分属性,方法 (如 'current_class_name_print': None, 'flag': True)
  47. # 因为这在传进来时候并没有绑定这些参数方法啊,是后面代码 手动绑定的啦 哈哈哈哈或或或
  48. object_from_objectcreator = ObjectCreator()
  49. print(object_from_objectcreator.flag)
  50. # 实际上这里返回了
  51. object_from_objectcreator.get_metaclass
  52. object_from_objectcreator.get_tobe_created_class
  53. object_from_objectcreator.get_bases_classess_tuple
  54. object_from_objectcreator.get_attrs_hold_dict
  55. # out:
  56. # current_class_name: <class '__main__.ObjectCreatorMetaClass'>
  57. # class_tobe_created_name: ObjectCreator
  58. # base_classess_name_tuple: (<class 'object'>,)
  59. # attrs_hold_dict: {'__qualname__': 'ObjectCreator', '__module__': '__main__'}
  60. # <class '__main__.ObjectCreatorMetaClass'>
  61. # ObjectCreator
  62. # (<class 'object'>,)
  63. # {'get_bases_classess_tuple': (<class 'object'>,), '__qualname__': 'ObjectCreator', 'get_metaclass': <class '__main__.ObjectCreatorMetaClass'>, '__module__': '__main__', 'get_tobe_created_class': 'ObjectCreator', 'flag': True}
  64. # True
  65. # {'__module__': '__main__',
  66. # '__qualname__': 'ObjectCreator',
  67. # 'flag': True,
  68. # 'get_attrs_hold_dict': {...},
  69. # 'get_bases_classess_tuple': (object,),
  70. # 'get_metaclass': __main__.ObjectCreatorMetaClass,
  71. # 'get_tobe_created_class': 'ObjectCreator'}
  72. # 到目前为止,我认为元类来创建 类 ,然后 类再创建对象的过程
  73. # 应该是 定义一个元类继承 type 这个 class 然后 覆写它的 __new__ 方法, TBD。。。
  74. # 曾经沧海,写完下面这个自动转换要被创建的类的属性为大写 , 元类也就会了
  75. class Upper_attr(type):
  76. def __new__(cls,name,bases,attr_dict):
  77. attr_dict = dict( (name.upper(),value) for name,value in attr_dict.items() if not name.startswith('__'))
  78. print(attr_dict)
  79. return super(Upper_attr,cls).__new__(cls,name,bases,attr_dict)
  80. class Foo(object,metaclass = Upper_attr):
  81. bar = 'bip'
  82. pass
  83. hasattr(Foo,'BAR')
  84. {'BAR': 'bip'}
  85. True
  86. # 思考为什么 构造函数 __init__ 不能用 lambda 来写函数体 , 因为,lambda 冒号后边必须接的是一个 表达式而非语句
  87. def __init__(self, x):
  88. self.x = x
  89. def printX(self):
  90. print(self.x)
  91. Test = type('Test', (object,), {'__init__': __init__, 'printX': printX})
  92. class TestMetaclass(type):
  93. def __new__(cls,name,bases,attr_dict):
  94. attr_dict['__init__'] = __init__
  95. attr_dict['printX']= lambda self:print(self.x)
  96. return super(TestMetaclass,cls).__new__(cls,name,bases,attr_dict)
  97. class Test(object,metaclass = TestMetaclass):
  98. pass
  99. Test('123').printX()

IO , 文件 , 内存, 字符,字节 类似于 java 的 IO

  1. import os
  2. file_list = os.listdir('.')
  3. for file in file_list:
  4. file_name,file_extension = os.path.splitext(file)
  5. if file_extension == '.csv':
  6. try:
  7. f = open(file,'r')
  8. print(f.read())
  9. print('file name: ',file_name+file_extension)
  10. except IOError as ioe:
  11. print(e)
  12. finally:
  13. if f:
  14. f.close()
  15. print(file_name,'<----->',file_extension)
  16. gender,age,drug,complication
  17. 0,1,3,5
  18. 1,3,2,3
  19. 0,5,1,2
  20. 0,2,3,3
  21. 1,7,3,2
  22. 0,6,3,4

file name: mock_data.csv

mock_data <-----> .csv

加上 编码,解码方式

  1. file_list = os.listdir('.')
  2. kw = {'encoding':'utf8'}
  3. for file in file_list:
  4. file_name,file_extension = os.path.splitext(file)
  5. if file_extension == '.csv':
  6. try:
  7. f = open(file,'r',**kw)
  8. print(f.read())
  9. print('file name: ',file_name+file_extension)
  10. except IOError as ioe:
  11. print(e)
  12. finally:
  13. if f:
  14. f.close()
  15. print(file_name,'<----->',file_extension)
  16. file_list = os.listdir('.')
  17. kw = {'encoding':'utf8'}
  18. for file in file_list:
  19. file_name,file_extension = os.path.splitext(file)
  20. if file_extension == '.csv':
  21. try:
  22. f = open(file,'r',**kw)
  23. # print(f.read())
  24. for line in f.readlines():
  25. print(line)
  26. print('file name: ',file_name+file_extension)
  27. except IOError as ioe:
  28. print(e)
  29. finally:
  30. if f:
  31. f.close()
  32. print(file_name,'<----->',file_extension)
  33. # 使用 with 表达式,相当于 java 中的 try(Autoclosable Resources) 语法糖,自动关闭资源
  34. file_list = os.listdir('.')
  35. kw = {'encoding':'utf8','errors':'ignore'}
  36. for file in file_list:
  37. file_name,file_extension = os.path.splitext(file)
  38. if file_extension == '.csv':
  39. with open(file,'r',**kw) as f:
  40. for line in f.readlines():
  41. print(line.strip()) # 去掉末尾的换行符
  42. print(file_name,'<----->',file_extension)
  43. # 读写二进制文件 是不能加 errors 参数的
  44. >>> with open('9.jpg','rb',errors='ignore') as fr:
  45. ... with open('99.jpg','wb') as fw:
  46. ... for line in fr.readlines():
  47. ... fw.write(line)
  48. ...
  49. Traceback (most recent call last):
  50. File "<stdin>", line 1, in <module>
  51. ValueError: binary mode doesn't take an errors argument
  52. # StringIO , python 3 中 是 from io import StringIO ,内存读写
  53. # 方式一:
  54. f = StringIO()
  55. f.write('Hello\nWorld!\n')
  56. print(f.getvalue())
  57. # 方式二:
  58. from io import StringIO
  59. f = StringIO('Hello\nWorld!\n')
  60. # print(f.getvalue())
  61. while True:
  62. s = f.readline()
  63. if s == '':
  64. break
  65. print(s.strip())
  66. # StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
  67. # BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
  68. from io import BytesIO
  69. f = BytesIO()
  70. f.write('中文'.encode('utf-8'))
  71. print(f.getvalue())
  72. 结果:
  73. b'\xe4\xb8\xad\xe6\x96\x87'
  74. # 解码:
  75. from io import BytesIO
  76. f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
  77. bcontent = f.read()
  78. print(bcontent.decode('utf-8'))
  79. 与上一种utf-8 编码相反,用 utf-8 解码, 结果如下:
  80. '中文'

文件夹目录以及文件相关操作

  1. # 在当前路径下查找包含指定字符串的 所有文件名,并返回。如果是子目录,需要用到递归,没有写,有空写写
  2. import os
  3. def search_file(filename):
  4. return [file for file in os.listdir('.') if os.path.isfile(file) and filename in file]
  5. for name in search_file('并'):
  6. print(name)
  7. 并发症逻辑回归准确率.ipynb
  8. 并发症概率模型.ipynb
  9. # api 集中:
  10. os.path.isdir(x)
  11. os.listdir('.')
  12. os.path.isfile(x)
  13. os.path.splitext(x)[1]=='.py'
  14. os.name # 操作系统类型 nt
  15. os.uname() # 注意uname()函数在Windows上不提供,也就是说,os模块的某些函数是跟操作系统相关的。
  16. os.environ # 在操作系统中定义的环境变量,全部保存在os.environ这个变量中,可以直接查看:
  17. os.environ.get('PATH')
  18. # 查看当前目录的绝对路径:
  19. >>> os.path.abspath('.')
  20. '/Users/michael'
  21. # 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
  22. >>> os.path.join('/Users/michael', 'testdir')
  23. '/Users/michael/testdir'
  24. # 然后创建一个目录:
  25. >>> os.mkdir('/Users/michael/testdir')
  26. # 删掉一个目录:
  27. >>> os.rmdir('/Users/michael/testdir')
  28. # 对文件重命名:
  29. >>> os.rename('test.txt', 'test.py')
  30. # 删掉文件:
  31. >>> os.remove('test.py')
  32. >>> os.path.split('/Users/michael/testdir/file.txt')
  33. ('/Users/michael/testdir', 'file.txt')
  34. 但是复制文件的函数居然在os模块中不存在!原因是复制文件并非由操作系统提供的系统调用。理论上讲,我们通过上一节的读写文件可以完成文件复制,只不过要多写很多代码。
  35. 幸运的是shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充。

序列化 (内存流向磁盘的过程)与 反序列化(磁盘流向内存的过程)

  1. # 序列化
  2. import pickle
  3. person = {'name':'Bob','age':18,'gender':'Male'}
  4. d = pickle.dumps(person)
  5. with open('dump.txt','wb') as fw:
  6. pickle.dump(d,fw)
  7. # 反序列化
  8. with open('dump.txt','rb') as fr:
  9. d=pickle.load(fr)
  10. print(d)

序列化为json 串存储到磁盘, 反序列化从磁盘读取 json 串到内存转化为python对象

  1. import json
  2. person = dict(name = 'Tom',age = 18,gender='Male')
  3. # dumps 将dict 转成 json 字符串
  4. j = json.dumps(person)
  5. with open('json.txt','w') as fw:
  6. # dump 序列化 json 串为文件或类文件对象 (file-like Object)
  7. json.dump(j,fw)
  8. # loads 方法将 json串反序列化
  9. json.loads(j)
  10. with open('json.txt','r') as fr:
  11. # load 方法将从文件中读取字符串并反序列化为json 串,同时你会发现是反序的
  12. k = json.load(fr)
  13. print(k)

再进一阶,序列化与反序列化 json 串 between 对象

  1. import json
  2. class Student(object):
  3. def __init__(self,name,age,sex):
  4. self.name = name
  5. self.age = age
  6. self.sex = sex
  7. s = Student('Tom',18,'Male')
  8. def student2str(std):
  9. return dict(name=std.name,age=std.age,sex=std.sex)
  10. json.dumps(student2str(s))
  11. json.dumps(s,default=lambda obj:obj.__dict__)
  12. '{"sex": "Male", "age": 18, "name": "Tom"}'
  13. #将上面的 json 字符串转换为 Student 对象
  14. json_str = '{"sex": "Male", "age": 18, "name": "Tom"}'
  15. def dict2student(d):
  16. return Student(d['name'],d['age'],d['sex'])
  17. s = json.loads(json_str,object_hook=dict2student)
  18. s.name
  19. 结果:
  20. 'Tom'

小结

Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。

json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们#### 又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。

内建模块以及常用第三方模块

  1. import urllib.request as urllib2
  2. import random
  3. ua_list=["Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
  4. "Mozilla/5.0 (Windows NT 6.1; rv2.0.1) Gecko/20100101 Firefox/4.0.1",
  5. "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
  6. "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
  7. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"]
  8. u_agent = random.choice(ua_list)
  9. # print(u_agent)
  10. url = 'http://www.baidu.com'
  11. request = urllib2.Request(url=url)
  12. request.add_header("User_agent",u_agent)
  13. response = urllib2.urlopen(request)
  14. print(response.read())

其他

  1. 标准数据类型
  2. Python3 中有六个标准的数据类型:
  3. Number(数字)
  4. String(字符串)
  5. List(列表)
  6. Tuple(元组)
  7. Sets(集合)
  8. Dictionary(字典)
  9. Python3 的六个标准数据类型中:
  10. 不可变数据(四个):Number(数字)、String(字符串)、Tuple(元组)、Sets(集合);
  11. 可变数据(两个):List(列表)、Dictionary(字典)。
  12. Set(集合)
  13. 集合(set)是一个无序不重复元素的序列。
  14. 基本功能是进行成员关系测试和删除重复元素。
  15. # 字符串的一些内建函数需要掌握 ,首字母大写 capitalize(),lower(),upper() 等等
  16. a = 'frank'
  17. a.capitalize()
  18. 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
  19. # set可以进行集合运算
  20. a = set('abracadabra')
  21. b = set('alacazam')
  22. print(a)
  23. print(a - b) # a和b的差集
  24. print(a | b) # a和b的并集
  25. print(a & b) # a和b的交集
  26. print(a ^ b) # a和b中不同时存在的元素
  27. dict_1 = dict(name='frank',age=18) # 这写法我喜欢
  28. dict_1 = {'name':'frank','age':18} # 这写法也能接受
  29. dict_1 = dict([('name','frank'),('age',18)]) # 这种写法我觉得纯粹是有病。。。
  30. 删除引用,估算引用,查询引用
  31. del b
  32. eval('b')
  33. hex(id(b)) # 16 进制 hash值
  34. # str()出来的值是给人看的。。。repr()出来的值是给python看的,可以通过eval()重新变回一个Python对象
  35. a = 'a'
  36. eval('a')
  37. hex(id(a))
  38. eval(repr(a))
  39. # print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":
  40. # 不换行输出
  41. print( x, end=" " )
  42. print( y, end=" " )
  43. dict items() , keys(), values()
  44. list pop , append
  45. import keyword
  46. keyword.kwlist
  47. # dict 是个好命令
  48. dir(dict)
  49. '__setitem__',
  50. '__sizeof__',
  51. '__str__',
  52. '__subclasshook__',
  53. 'clear',
  54. 'copy',
  55. 'fromkeys',



python 日志

  1. # 这段代码保存为 config.py
  2. # -*- coding: utf-8 -*-
  3. __author__ = 'Frank Li'
  4. import logging
  5. class Config():
  6. # 创建一个logger
  7. logger = logging.getLogger('statisticNew')
  8. logger.setLevel(logging.DEBUG)
  9. # 创建一个handler,用于写入日志文件
  10. fh = logging.FileHandler('test.log')
  11. fh.setLevel(logging.DEBUG)
  12. # 再创建一个handler,用于输出到控制台
  13. ch = logging.StreamHandler()
  14. ch.setLevel(logging.DEBUG)
  15. # 定义handler的输出格式
  16. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  17. fh.setFormatter(formatter)
  18. ch.setFormatter(formatter)
  19. # 给logger添加handler
  20. logger.addHandler(fh)
  21. logger.addHandler(ch)
  22. def getLog(self):
  23. return self.logger

引用上段代码保存的额 config.py 文件里的module

  1. __author__ = 'Frank Li'
  2. from config import Config
  3. if __name__ == '__main__':
  4. conf = Config()
  5. logger = conf.getLog()
  6. logger.info('foorbar')
  7. boy = "Frank Li"
  8. is_handsome = True
  9. logger.info("boy=%s,is_handsome=%s",boy,is_handsome)
  10. # 异常处理,以后尽量不要用山寨的 print 了
  11. try:
  12. ....
  13. except Exception as e:
  14. logger.exception('ERROR readFile:%s,%s' % (path,str(e)))

编码规范 , 变量定义

  1. # Python变量命名用法(一般变量、常量、私有变量、内置变量)
  2. #coding:utf8
  3. __author__ = "libingxian"
  4. class TestDemo(object):
  5. """
  6. Python变量命名用法(以字符或者下划线开头,可以包括字母、数字、下划线,区别大小写)
  7. 一般变量
  8. 常量
  9. 私有变量
  10. 内置变量
  11. """
  12. FINAL_VAR = "V1.0" # 常量,不可修改的变量,以大写字母或加下划线命名,这个只是约定,即使更改了也不会报错
  13. class_name = "TestDemo" # 常见变量命名,
  14. __maker__ = 'libingxian' # 内置变量,两个前置下划线和两个后置下划线,内置对象所具有,声明时不可与内置变量名的重复
  15. def __init__(self):
  16. self.__private_var = "private" # 私有变量,以两个前置下划线开头,只能在本类中使用,类外强制访问会报错
  17. self.public_var = "public" # 一般变量
  18. def __private_method(self):# 私有方法,以两个下划线开头、字母小写,只能在本类中使用,类外强制访问会报错
  19. print "i am private"
  20. def public_method(self):
  21. print "i am public"
  22. test_demo = TestDemo()
  23. print test_demo.FINAL_VAR # 访问常量
  24. print test_demo.public_var # 访问一般变量
  25. print test_demo.__private_var # 访问私有变量,运行会报错
  26. test_demo.__private_method() # 访问私有方法,运行会报错

字典操作 dict_1.update(dict_2) 合并 dict

  1. dict_1 = {'name':'Frank','age':18}
  2. gender_dict = {'gender':'Male'}
  3. dict_1.update(gender_dict)
  4. print(dict_1)

字典推导式

  1. mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
  2. mcase_frequency = {
  3. k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
  4. for k in mcase.keys()
  5. }
  6. # mcase_frequency == {'a': 17, 'z': 3, 'b': 34}
  7. # key,value 交换
  8. >>> {value:key for key,value in dict_1.items()}
  9. {'Frank': 'name', 18: 'age'}

由 两个 list 合并 dict 原理是利用 zip 合并成 ((key1,value1),(key2,value2)) 然后用 dict[key] = value 方式

  1. list_1 = ['name','age']
  2. list_2 = ['Frank',18]
  3. person_dict = {}
  4. for key,value in zip(list_1,list_2):
  5. person_dict[key] = value
  6. print(person_dict)
  7. # 反过来 zip(*zipped) ==> flattern
  8. dict_2 = dict(name='Frank',age=18)
  9. list_3,list_4 = zip(*[ [key,value] for key,value in dict_2.items()])
  10. list_3,list_4

list 去重

  1. # 方法一
  2. l1 = ['b','c','d','b','c','a','a']
  3. l2 = {}.fromkeys(l1).keys()
  4. print(l2)
  5. # 方法二
  6. l3 = list(set(l1))
  7. # 方法三
  8. >>> a=[1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]
  9. >>> a.sort()
  10. >>> a
  11. [0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 7, 7, 8, 9, 10]
  12. >>> last = a[-1]
  13. >>> for i in range(len(a)-2,-1,-1):
  14. ... if last == a[i]:
  15. ... del a[i]
  16. ... else:
  17. ... last = a[i]
  18. ...
  19. >>> a
  20. [0, 1, 2, 3, 4, 5, 7, 8, 9, 10]
  21. # 封装成方法 distinct
  22. >>> def distinct(lst):
  23. ... lst.sort()
  24. ... last = lst[-1] # 这里不正向的原因是lst长度会改变
  25. ... for i in range(len(lst)-2,-1,-1): # 倒序来比较列表
  26. ... if last == lst[i]:
  27. ... del lst[i] # 如果与已经有的值相同则删除
  28. ... else: # 否则则将 last 指向前一个元素
  29. ... last = lst[i]
  30. ... return lst
  31. distinct([1,2,4,2,4,5,7,10,5,5,7,8,9,0,3])
  32. # 三元运算 还可以用 元组条件表达式的三元运算 is_fat =('not fat','fat') [is_state]
  33. >>> is_state = True
  34. >>> is_fat = 'fat' if is_state else 'not fat'
  35. >>> is_fat
  36. 'fat'
  37. # 优雅地查出重复数据
  38. >>> str_list = ['a','b','a','c','d','b','c']
  39. >>> [s for s in str_list if str_list.count(s) >1]
  40. ['a', 'b', 'a', 'c', 'b', 'c']
  41. >>> set([s for s in str_list if str_list.count(s) >1])
  42. {'a', 'c', 'b'}
  43. # 求交集 差集
  44. >>> str_list2 = ['a','b']
  45. >>> str_list = set([s for s in str_list if str_list.count(s) >1])
  46. >>> str_list.intersection(str_list2)
  47. {'a', 'b'}
  48. >>> str_list.difference(str_list2)
  49. {'c'}

列表排序

  1. 列表排序
  2. a = [(1, 2), (4, 1), (9, 10), (13, -3)]
  3. a.sort(key=lambda x: x[1])
  4. print(a)
  5. # Output: [(13, -3), (4, 1), (1, 2), (9, 10)]

列表并行排序

  1. list_1 = [8,4,3,2,7,6,5]
  2. list_2 = ['e','d','c','y','i','o','p']
  3. data = zip(list_1,list_2)
  4. data = sorted(data)
  5. list1, list2 = map(lambda t: list(t), zip(*data))
  6. print(list1)
  7. print(list2)

模拟 with open

  1. >>> class File(object):
  2. ... def __init__(self,file_name,method):
  3. ... self.file_obj = open(file_name,method)
  4. ... def __enter__(self):
  5. ... return self.file_obj
  6. ... def __exit__(self,type,value,traceback):
  7. ... self.file_obj.close()
  8. ...
  9. >>> with File('C:/Users/FrankLi/Desktop/Demo.java','r') as f:
  10. ... for line in f.readlines():
  11. ... print(line)
  12. ...
  13. class Demo{
  14. public static void main(String[] args){
  15. System.out.println("Hello world!");
  16. }
  17. }
  18. 我们的__exit__函数接受三个参数。这些参数对于每个上下文管理器类中的__exit__方法都是必须的。我们来谈谈在底层都发生了什么。
  19. with语句先暂存了File类的__exit__方法
  20. 然后它调用File类的__enter__方法
  21. __enter__方法打开文件并返回给with语句
  22. 打开的文件句柄被传递给opened_file参数
  23. 我们使用.write()来写文件
  24. with语句调用之前暂存的__exit__方法
  25. __exit__方法关闭了文件

类似于 scala 的 flattern 列表展平

  1. >>> import itertools
  2. >>> a_list = [[1,2],[3,4],[5,6]]
  3. >>> print(itertools.chain(*a_list))
  4. <itertools.chain object at 0x039E6090>
  5. >>> print(list(itertools.chain(*a_list)))
  6. [1, 2, 3, 4, 5, 6]
  7. >>> print(list(itertools.chain.from_iterable(a_list)))
  8. [1, 2, 3, 4, 5, 6]
  9. >>> l = [[1,2,3],[4,5,6], [7], [8,9]]
  10. >>> [item for sublist in l for item in sublist] # 推导式中两层 for 循环也可以实现
  11. [1, 2, 3, 4, 5, 6, 7, 8, 9]

for - else 结构

  1. for n in range(2, 100):
  2. for x in range(2, n):
  3. if n % x == 0:
  4. print(n, 'equals', x, '*', n / x)
  5. break
  6. else:
  7. # loop fell through without finding a factor
  8. print(n, 'is a prime number')
  1. # 替代 switch case 方案 字典映射
  2. >>> def switch(x):
  3. ... return {'0':0,'1':1,'2':2}.get(x,'nothing')
  4. ...
  5. >>> switch('0')
  6. 0
  7. >>> switch('3')
  8. 'nothing'

16.检查一个字符串是否是一个数字?

  1. In[22]: x = '569789'
  2. In[23]: x.isdigit()
  3. Out[23]: True
  4. In[24]: y = 'gdf2667'
  5. In[25]: y.isdigit()
  6. Out[25]: False

17.查找列表中某个元素的下标?

  1. In[26]: ['a','b','c'].index('b')
  2. Out[26]: 1

18.如何在列表中随机取一个元素?

  1. import random
  2. f= ['a', 'b', 'c']
  3. print(random.choice(f))
  1. # 字典排序
  2. >>> dict_1 = {'a':3,'b':1,'c':2}
  3. >>> sorted(dict_1.items(),key=lambda x:x[1])
  4. [('b', 1), ('c', 2), ('a', 3)]
  5. >>> import operator
  6. >>> file_dict={"a":1,"b":2,"c":3}
  7. >>> sorted(file_dict.items(),key = operator.itemgetter(1),reverse=True)
  8. [('c', 3), ('b', 2), ('a', 1)]
  1. # 字符串的不可变形 = immutability
  2. Str1 = 'Yuxl'
  3. print(Str1)
  4. try:
  5. Str1[0] = 'XX'
  6. except:
  7. print("不可更改")
  8. Yuxl
  9. 不可更改
  10. >>> import random
  11. >>> def g_rand_range(max):
  12. ... for i in range(1,max+1,1):
  13. ... yield random.randint(1,10)
  14. ...
  15. >>> for i in g_rand_range(10):
  16. ... print(i)

别人的总结图

JAVA vs PYTHON (还没细看)

总结:

至此,关于 python 基础的总结基本完结,其中有涉及到高阶知识 , 元类,位置参数关键字参数 可变参数(*args type: tuple,**kwargs type: dict),

生成器,装饰器,函数式编程风格的 map reduce filter sorted上下文管理器, 要补充的有 : 进程线程协程,异步io

接下来的时间应该是 学习 python 的重要常用模块(Pandas,Numpy,Scipy,PIL pillow , opencv,sk-learn,xgboost,爬虫库 scrappy等)以及框架(Django)

最后感慨一下,如果一开始碰到了python 也许根本就不会去学java了,感觉python的设计思想比较符合我的思想各种黑魔法的魅力吸引着我!!!

(虽然java不可否认也是一门优雅的工程化设计语言但不够精简,语法冗长)。。。life is short , I use python and java ! 其实语言本身没有好坏,

只有适用场景(多一门语言能力便多一种工具,而工具可以提高效率!),

每一门语言都有自己的设计思想,一个合格的程序员应该多学几门语言,了解怎样用不同的方法和思维去解决同一个问题。因此学习多门并不仅仅是为了更好的装逼!!!

我曾经还一直在想为什么没有出现一门语言一统天下呢 现在想想也是天真。。。

不过语言始终流于招式,接下来是要修炼一波内功了,算法才是灵魂!

python 基础部分重点复习整理--从意识那天开始进阶--已结的更多相关文章

  1. python 基础部分重点复习整理2

    把这里的题目争取刷一遍 博客记录 python的ORM框架peewee SQLAlchemy psycopg2 Django 在1 的基础上,重点突出自己以前没注意的,做到精而不杂!!! Python ...

  2. python基础内容扩展复习

    目录 一.关于编辑器 二.解释型和编译型 三.数据类型 1 一切皆对象 2 深浅拷贝 3 可变类型和不可变类型 四.闭包函数 一.关于编辑器 python开发:pycharm(收费),vscode(免 ...

  3. python基础一 day13 复习

    # 函数 —— 2天 # 函数的定义和调用 # def 函数名(形参): #函数体 #return 返回值 #调用 函数名(实参) # 站在形参的角度上 : 位置参数,*args,默认参数(陷阱),* ...

  4. python基础一 day7 复习文件操作

    read()原样输出 读取出来的是字符串类型 readline()输出一行 读取出来的是字符串类型 readlines()把每行文本作为一个字符串存入列表,并返回列表 打开方式: b以bytes类型打 ...

  5. Java基础(面试复习整理)

    基础知识和语法 Java语言初识 计算机语言发展 机器语言.汇编.C.C++.Java Java的诞生与发展 1995 JavaSE JavaME Android JavaEE 2006(大数据) H ...

  6. python基础一 day17 复习

    # 迭代器# 生成器进阶 # 内置函数 # 55个 # 带key的 max min filter map sorted # 思维导图上红色和黄色方法必须会用 # 匿名函数 # lambda 参数,参数 ...

  7. python基础一 day15 复习

    迭代器和生成器迭代器 可迭代协议 —— 含有iter方法的都是可迭代的 迭代器协议 —— 含有next和iter的都是迭代器 特点 节省内存空间 方便逐个取值,一个迭代器只能取一次.生成器 —— 迭代 ...

  8. python基础一 day14 复习

    迭代器和生成器迭代器:双下方法 : 很少直接调用的方法.一般情况下,是通过其他语法触发的可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))可迭代的一定 ...

  9. python基础一 day5 复习

    bytes类型默认编码方式是utf-8和gbk,反正不是unicode strn内部的编码方式是Unicode         range相当于只有一次,第一次之后相当于一个有序列表.range顾头不 ...

随机推荐

  1. http to https

    https://www.cnblogs.com/powertoolsteam/p/http2https.html

  2. Github pages + Minimal-Mistakes + Disqus建立个人博客记录

    本文详细记录了利用Github pages建立个人博客的步骤. github pages官方推荐使用Jekyll生成静态网页,jekyll支持各种不同的主题,Minimal-Mistakes是一个功能 ...

  3. 详细解析 nginx uri 如何匹配 location 规则

    location 是 nginx 配置中出现最频繁的配置项,一个 uri 是如何与多个 location 进行匹配的? 在有多个 location 都匹配的情况下,如何决定使用哪一个 location ...

  4. Web挂马方式整理

    一:框架挂马 <iframe src=地址 width=0 height=0></iframe> 二:js文件挂马 首先将以下代码 document.write("& ...

  5. VMware 虚拟机CentOS 7 网路连接配置 无eth0简单解决办法

    个人博客:http://www.cnblogs.com/miaojinmin799/ 在前面几步基本和网上linux配置差不多,最后一步要配置eth0时出现如图所示结果使用ifconfig -a命令 ...

  6. Answer My Questions

    回答自己的问题,真棒!断电让自己的工作重来.真棒! 阅读以前自己的博客,发现问题都已经有了答案. (1).想要成为一名专业的软件工程师,首先得是有相关的资格证书,这个可以通过软考获得.然后在职场中锻炼 ...

  7. OS X(10.10) python3.4 matplotlib的安装

    最近在用python做一些数据处理相关的工作,当然少不了matplotlib这个模块.之前在windows下分分钟安装成功,结果到了mac下死活编译不过去. 最后还是在stackoverflow上找到 ...

  8. 3D开机动画

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  9. cglib动态代理是通过继承父类的方式进行代理的 不是通过接口方式进行动态代理的 因此可以对普通的类进行代理

    cglib动态代理是通过继承父类的方式进行代理的 不是通过接口方式进行动态代理的

  10. Linux命令行上传本地文件到服务器 、 下载服务器文件到本地

    sh使用命令: scp 将本地文件上传至服务器 第一个是本地文件的路径/文件名, 例如 ./index.tar.gz  . index.html . bg.png 等 第二个是要上传到的服务器的位置  ...