编程艺术

编程艺术

PHP安装常见错误

编程艺术 chris 发表了文章 0 个评论 11 次浏览 1 天前 来自相关话题

configure: error: Please reinstall the BZip2 distribution 解决: yum install bzip2 ...查看全部
 configure: error: Please reinstall the BZip2 distribution

解决: yum install bzip2-devel
 

configure: error: Please reinstall the libcurl distribution – easy.h should be in/include/curl/

解决: yum install curl-devel
 

configure: error: DBA: Could not find necessary header file(s).

解决: yum install db4-devel
 

configure: error: jpeglib.h not found.

解决: yum install libjpeg-devel
 

configure: error: png.h not found.

解决: yum install libpng-devel
 

configure: error: freetype.h not found.

解决: yum install -y freetype freetype-devel
 

configure: error: libXpm.(a|so) not found.

解决: yum install libXpm-devel
 

configure: error: Unable to locate gmp.h

解决: yum install gmp-devel
 

configure: error: utf8_mime2text() has new signature, but U8T_CANONICAL is missing. This should not happen. Check config.log for additional information.

解决: yum install libc-client-devel
 

configure: error: Cannot find ldap.h

解决: yum install openldap-devel
 

configure: error: ODBC header file ‘/usr/include/sqlext.h’ not found!

解决:yum install unixODBC-devel
 

configure: error: Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path

解决: yum install postgresql-devel
 

configure: error: Please reinstall the sqlite3 distribution

解决: yum install sqlite-devel
 

configure: error: Cannot find pspell

解决: yum install aspell-devel
 

config.log for more information.

解决: yum install net-snmp-devel
 

configure: error: xslt-config not found. Please reinstall the libxslt >= 1.1.0 distribution

解决: yum install libxslt-devel
 

configure: error: xml2-config not found. Please check your libxml2 installation.

解决: yum install libxml2-devel
 

configure: error: Could not find pcre.h in /usr

解决: yum install pcre-devel
 

configure: error: Cannot find MySQL header files under yes. Note that the MySQL client library is not bundled anymore!

解决: yum install mysql-devel


configure: error: ODBC header file ‘/usr/include/sqlext.h’ not found!

解决: yum install unixODBC-devel
 

configure: error: Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path

解决:yum install postgresql-devel
 

configure: error: Cannot find pspell

解决: yum install pspell-devel
 

configure: error: Could not find net-snmp-config binary. Please check your net-snmp installation.

解决: yum install net-snmp-devel
 

configure: error: xslt-config not found. Please reinstall the libxslt >= 1.1.0 distribution

解决: yum install libxslt-devel
 

configure: error: mcrypt.h not found. Please reinstall libmcrypt.

解决: yum install -y libmcrypt-devel

PHP GD编译报错 error: png.h: No such file or directory

回复

编程艺术 chris 发起了问题 1 人关注 0 个回复 23 次浏览 5 天前 来自相关话题

2020 GopherCon大会PPT,一睹为快

回复

编程艺术 OS小编 发起了问题 1 人关注 0 个回复 28 次浏览 2020-11-17 11:26 来自相关话题

Pyhton列表去重方法总结

编程艺术 Ansible 发表了文章 0 个评论 77 次浏览 2020-11-02 00:22 来自相关话题

Python列表去重在Python应用编程中,是一种非常常见的应用技巧,有些场景下需要统计出来的列表中去重,避免重复统计。 1. 通过字典去重#!/usr/bin/env python3 ...查看全部

Python列表去重在Python应用编程中,是一种非常常见的应用技巧,有些场景下需要统计出来的列表中去重,避免重复统计。


1. 通过字典去重

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = {}.fromkeys(job).keys()
print(list(jobs))

结果:


['Sale', 'Dev', 'OPS', 'Presale', 'Test']

解释:


Python 字典 fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值。


语法:


dict.fromkeys(seq[, value])
  • seq - 字典键值列表。
  • value - 可选参数, 设置键序列(seq)的值。

该方法返回一个新字典, .keys 函数以列表返回一个字典所有的键。



2. 通过集合去重

大家都知道在Python数据结构中集合是天生去重的,所以我们可以利用这一特性来达到列表去重的效果。


格式: list(set(mylist))


#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = list(set(job))

由于采用集合,会导致原有的列表排序发生变化,此时可通过如下方法,保持列表原有顺序:


#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = list(set(job))
jobs.sort(key=job.index)


3. 使用itertools模块

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy
import itertools

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
job.sort()

job_group = itertools.groupby(job)
jobs = []
for k, g in job_group:
jobs.append(k)
print(jobs)

groupby 根据key(v)值分组的迭代器, 将key函数作用于原循环器的各个元素。根据key函数结果,将拥有相同函数结果的元素分到一个新的循环器。每个新的循环器以函数返回结果为标签。



4. 通过列表推导式去重

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']

jobs = []
[ jobs.append(i) for i in job if i not in jobs]

通过列表推导式,判断在不在新列表中的元素则添加到新列表中。



5. 利用lambda匿名函数和 reduce 函数处理

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy
from functools import reduce

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
func = lambda x,y:x if y in x else x + [y]
jobs = reduce(func, [[], ] + job)

Python parallel.futures如何检测失败的任务?

编程艺术 chris 回复了问题 2 人关注 1 个回复 65 次浏览 2020-10-17 15:00 来自相关话题

PHP5.4.45编译安装报错

编程艺术 空心菜 回复了问题 2 人关注 1 个回复 55 次浏览 2020-10-16 16:56 来自相关话题

Python如何替换掉字符串里面的单引号和双引号

编程艺术 空心菜 回复了问题 2 人关注 1 个回复 111 次浏览 2020-09-24 19:02 来自相关话题

Python下判断文件是否为二进制文件的三种方法

编程艺术 OpenSkill 发表了文章 0 个评论 91 次浏览 2020-09-18 18:27 来自相关话题

常用的有两种方法判断文件是否为二进制文件,最准确的就是把这两种方法结合起来更加准确点. 方法1利用codecs模块 ...查看全部

常用的有两种方法判断文件是否为二进制文件,最准确的就是把这两种方法结合起来更加准确点.


方法1利用codecs模块

它首先检查文件是否以BOM开始,如果不在初始8192字节内查找零字节:


import codecs

file_path = "/home/ubuntu/zgd/ztest/_gs418_510txp_v6.6.2.7.stk.extracted/test"

#: BOMs to indicate that a file is a text file even if it contains zero bytes.
_TEXT_BOMS = (
codecs.BOM_UTF16_BE,
codecs.BOM_UTF16_LE,
codecs.BOM_UTF32_BE,
codecs.BOM_UTF32_LE,
codecs.BOM_UTF8,
)


def is_binary_file(file_path):
with open(file_path, 'rb') as file:
initial_bytes = file.read(8192)
file.close()
return not any(initial_bytes.startswith(bom) for bom in _TEXT_BOMS) and b'\0' in initial_bytes

if __name__ == "__main__":
print is_binary_file(file_path)

上面is_binary_file()函数也可以改成下面的方式:


def is_binary_file(file_path):
with open(file_path, 'rb') as file:
initial_bytes = file.read(8192)
file.close()
for bom in _TEXT_BOMS:
if initial_bytes.startswith(bom):
continue
else:
if b'\0' in initial_bytes:
return True
return False


方法2利用magic模块

安装模块: pip install python-magic


def getFileType(ff):
mime_kw = 'x-executable|x-sharedlib|octet-stream|x-object' ###可执行文件、链接库、动态流、对象
try:
magic_mime = magic.from_file(ff, mime=True)
magic_hit = re.search(mime_kw, magic_mime, re.I)
if magic_hit:
return True
else:
return False
except Exception, e:
print e.message

最好的方法是对两种类型同时进行处理:


# -*- coding:utf-8 -*-
# @Author:zgd
# @time:2019/6/21
# @File:operateSystem.py

import magic
import re
import codecs

def is_binary_file_1(ff):
'''
根据text文件数据类型判断是否是二进制文件
:param ff: 文件名(含路径)
:return: True或False,返回是否是二进制文件
'''

TEXT_BOMS = (
codecs.BOM_UTF16_BE,
codecs.BOM_UTF16_LE,
codecs.BOM_UTF32_BE,
codecs.BOM_UTF32_LE,
codecs.BOM_UTF8,
)
with open(file_path, 'rb') as file:
CHUNKSIZE = 8192
initial_bytes = file.read(CHUNKSIZE)
file.close()
#: BOMs to indicate that a file is a text file even if it contains zero bytes.
return not any(initial_bytes.startswith(bom) for bom in TEXT_BOMS) and b'\0' in initial_bytes


def is_binwary_file_2(ff):
'''
根据magic文件的魔术判断是否是二进制文件
:param ff: 文件名(含路径)
:return: True或False,返回是否是二进制文件
'''

mime_kw = 'x-executable|x-sharedlib|octet-stream|x-object' ###可执行文件、链接库、动态流、对象
try:
magic_mime = magic.from_file(ff, mime=True)
magic_hit = re.search(mime_kw, magic_mime, re.I)
if magic_hit:
return True
else:
return False
except Exception, e:
return False


if __name__ == "__main__":
file_path = "/home/ubuntu/zgd/ztest/_gs418_510txp_v6.6.2.7.stk.extracted/D0"
print is_binary_file_1(file_path)
print is_binwary_file_2(file_path)
print any((is_binary_file_1(file_path), is_binwary_file_2(file_path)))


方法3判断是否有ELF头

根据文件中是否有ELF头进行判断文件是否为二进制文件


# 判断文件是否是elf文件
def is_ELFfile(filepath):
if not os.path.exists(filepath):
logger.info('file path {} doesnot exits'.format(filepath))
return False
# 文件可能被损坏,捕捉异常
try:
FileStates = os.stat(filepath)
FileMode = FileStates[stat.ST_MODE]
if not stat.S_ISREG(FileMode) or stat.S_ISLNK(FileMode): # 如果文件既不是普通文件也不是链接文件
return False
with open(filepath, 'rb') as f:
header = (bytearray(f.read(4))[1:4]).decode(encoding="utf-8")
# logger.info("header is {}".format(header))
if header in ["ELF"]:
# print header
return True
except UnicodeDecodeError as e:
# logger.info("is_ELFfile UnicodeDecodeError {}".format(filepath))
# logger.info(str(e))
pass

return False

Python下如何将字符串类型的列表转换为列表对象?

编程艺术 OS小编 回复了问题 3 人关注 1 个回复 167 次浏览 2020-09-18 01:18 来自相关话题

使用vscode的扩展pylance写的Python代码引入自定义的包找不到

编程艺术 OS小编 回复了问题 3 人关注 1 个回复 575 次浏览 2020-08-29 21:41 来自相关话题

图解Python 集合

编程艺术 空心菜 发表了文章 2 个评论 2014 次浏览 2016-08-10 23:41 来自相关话题

集合基本功能 集合是一个无序的,不重复的数据组合,用{}表示,它的主要作用如下: 去重,把一个列表变成集合,就会自动去重关系测试,测试两组数据之前的交集、差集、并集、子集等关系  集合创建: >>> ...查看全部


集合基本功能


集合是一个无序的,不重复的数据组合,用{}表示,它的主要作用如下:
  1. 去重,把一个列表变成集合,就会自动去重
  2. 关系测试,测试两组数据之前的交集、差集、并集、子集等关系

 集合创建:
>>> set_job = set(['DEV', 'OPS', 'DBA', 'QA', 'Sales'])
>>> set_man = set(('lucky', 'jack', 'andy', 'tom', 'andy', 'jim'))
>>> print(set_job, type(set_job))
{'DEV', 'OPS', 'Sales', 'QA', 'DBA'}
>>> print(set_man, type(set_man)) # 天生去重,只有一个andy了
{'andy', 'jack', 'lucky', 'tom', 'jim'}

 
元素添加:
>>> set_job = set(['DEV', 'OPS', 'DBA', 'QA', 'Sales'])
>>> set_job.add('HR') # add方法只能添加一个
>>> print(set_job)
{'QA', 'HR', 'Sales', 'DEV', 'OPS', 'DBA'}
>>> set_job.update(['FD', 'MD', 'MD'])
>>> print(set_job)
{'QA', 'HR', 'Sales', 'DEV', 'MD', 'OPS', 'FD', 'DBA'}
>>> set_job.update(('AD', 'PD')) # update方法可以添加是列表或者元组,去重,如果添加的为一个单独字符串,则把字符串拆成字母添加到集合中
>>> print(set_job)
{'QA', 'HR', 'PD', 'Sales', 'DEV', 'MD', 'OPS', 'AD', 'FD', 'DBA'}

元素删除:
>>> set_job = {'QA', 'HR', 'PD', 'Sales', 'DEV', 'MD', 'OPS', 'AD', 'FD', 'DBA'}
>>> set_job.remove('PD') # 删除指定元素
>>> set_job.remove('xx') # 元素不存在则报错 KeyError
Traceback (most recent call last):
File "", line 1, in
KeyError: 'xx'
>>> print(set_job)
{'QA', 'HR', 'MD', 'DEV', 'Sales', 'OPS', 'AD', 'FD', 'DBA'}
>>> set_job.pop() # 随机删除一个元素
'QA'
>>> print(set_job)
{'HR', 'MD', 'DEV', 'Sales', 'OPS', 'AD', 'FD', 'DBA'}
>>> set_job.discard('OPS') # 指定删除
>>> set_job.discard('xxx') # 不存在返回None,不会报KeyError
>>> print(set_job)
{'HR', 'MD', 'DEV', 'Sales', 'AD', 'FD', 'DBA'}

其他:
>>> set_job = {'QA', 'HR', 'PD', 'Sales', 'DEV', 'MD', 'OPS', 'AD', 'FD', 'DBA'}
>>> len(set_job)  # 集合长度
10
>>> 'QA' in set_job  # 判断是否在集合中
True
>>> 'XXX' not in set_job # 不在集合中
True
>>> for i in set_job:   # 循环
...     print(i)


集合关系测试


交集:
intercaiton.png
>>> set_a = {5, 6, 7, 8, 9, 10}
>>> set_b = {1, 2, 3, 4, 5, 6}
>>> print(set_a.intersection(set_b)) # 常规方式
{5, 6}
>>> print(set_a & set_b) # 运算符(&)方式
{5, 6}

并集
bingji.png
>>> set_a = {5, 6, 7, 8, 9, 10}
>>> set_b = {1, 2, 3, 4, 5, 6}
>>> set_c = set_a.union(set_b)    # 关键字union做并集运算 先后顺序无关,谁并谁都可以
>>> print(set_c)
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
>>> 
>>> set_c = set_a | set_b     # 运算符关键符 | 做并集运算  先后顺序无关,谁并谁都可以
>>> print(set_c)
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

差集
chaji.png
>>> set_a = {5, 6, 7, 8, 9, 10}
>>> set_b = {1, 2, 3, 4, 5, 6}
>>> set_c = set_a - set_b # a集合跟b集合做差集 关键符 -
>>> print(set_c)
{8, 9, 10, 7}
>>> set_d = set_b - set_a # b集合跟a集合做差集 关键符 -
>>> print(set_d)
{1, 2, 3, 4}
>>> set_c = set_a.difference(set_b) # a集合跟b集合做差集 关键字difference
>>> print(set_c)
{8, 9, 10, 7}
>>> set_d = set_b.difference(set_a) # b集合跟a集合做差集 关键字difference
>>> print(set_d)
{1, 2, 3, 4}

 
子集父集
fuziji.png

拿苹果来打比方就是,把苹果掰开,然后掰开的一小部分就是子集,然后整个苹果就是父集
>>> set_a = {5, 6, 7, 8, 9, 10}
>>> set_b = {1, 2, 3, 4, 5, 6}
>>> set_c = {7, 8, 9, 10}
>>> set_d = {1, 2, 3, 4}
>>> set_e = {5, 6}
>>> set_f = {11, 12, 13, 14, 15, 16}
>>> set_c.issubset(set_a) # 测试集合c是否是集合a的子集 放回布尔值 关键字issubset
True
>>> set_d.issubset(set_b) # 测试集合d是否是集合b的子集 返回布尔值 issubset
True
>>> set_e.issubset(set_a)
True
>>> set_e.issubset(set_b)
True
>>> set_e <= set_a # 测试集合e是否是集合a的子集 关键符 <=
True
>>> set_e <= set_b
True
>>> set_f.issuperset(set_a) # 测试f集合是否是a集合的父集
False
>>> set_a.issuperset(set_e) # 测试a集合是否是集合e的父集 关键字issuperset
True
>>> set_b >= set_e # 测试集合b是否是集合e的父集 关键符 >=
True
>>> set_b >= set_d
True

对称差集
对称差集就是两个集合去掉相同的部分,然后剩下的所有元素组成的集合
duichengchaji.png
>>> set_a = {5, 6, 7, 8, 9, 10}
>>> set_b = {1, 2, 3, 4, 5, 6}
>>> set_c = set_a.symmetric_difference(set_b) # 集合a和集合b做对称差集 关键字symmetric_difference
>>> print(set_c)
{1, 2, 3, 4, 7, 8, 9, 10}
>>> set_c = set_a ^ set_b # 集合a和集合b做对称差集 关键符 ^
>>> print(set_c)
{1, 2, 3, 4, 7, 8, 9, 10}
>>> set_c = set_b ^ set_a
>>> print(set_c)
{1, 2, 3, 4, 7, 8, 9, 10}

所有方法:
class set(object):
"""
set() -> new empty set object
set(iterable) -> new set object

Build an unordered collection of unique elements.
"""
def add(self, *args, **kwargs): # real signature unknown
"""
Add an element to a set.

This has no effect if the element is already present.
"""
pass

def clear(self, *args, **kwargs): # real signature unknown
""" Remove all elements from this set. """
pass

def copy(self, *args, **kwargs): # real signature unknown
""" Return a shallow copy of a set. """
pass

def difference(self, *args, **kwargs): # real signature unknown
"""
Return the difference of two or more sets as a new set.

(i.e. all elements that are in this set but not the others.)
"""
pass

def difference_update(self, *args, **kwargs): # real signature unknown
""" Remove all elements of another set from this set. """
pass

def discard(self, *args, **kwargs): # real signature unknown
"""
Remove an element from a set if it is a member.

If the element is not a member, do nothing.
"""
pass

def intersection(self, *args, **kwargs): # real signature unknown
"""
Return the intersection of two sets as a new set.

(i.e. all elements that are in both sets.)
"""
pass

def intersection_update(self, *args, **kwargs): # real signature unknown
""" Update a set with the intersection of itself and another. """
pass

def isdisjoint(self, *args, **kwargs): # real signature unknown
""" Return True if two sets have a null intersection. """
pass

def issubset(self, *args, **kwargs): # real signature unknown
""" Report whether another set contains this set. """
pass

def issuperset(self, *args, **kwargs): # real signature unknown
""" Report whether this set contains another set. """
pass

def pop(self, *args, **kwargs): # real signature unknown
"""
Remove and return an arbitrary set element.
Raises KeyError if the set is empty.
"""
pass

def remove(self, *args, **kwargs): # real signature unknown
"""
Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.
"""
pass

def symmetric_difference(self, *args, **kwargs): # real signature unknown
"""
Return the symmetric difference of two sets as a new set.

(i.e. all elements that are in exactly one of the sets.)
"""
pass

def symmetric_difference_update(self, *args, **kwargs): # real signature unknown
""" Update a set with the symmetric difference of itself and another. """
pass

def union(self, *args, **kwargs): # real signature unknown
"""
Return the union of sets as a new set.

(i.e. all elements that are in either set.)
"""
pass

def update(self, *args, **kwargs): # real signature unknown
""" Update a set with the union of itself and others. """
pass

Python菜鸟之路基础篇(一)

编程艺术 空心菜 发表了文章 3 个评论 2536 次浏览 2016-07-26 00:55 来自相关话题

Hello World 学习任何一门语言,我想大家写的以一句就是hello world吧,下面我们来看看Python的hello world 创建一个hello.py的文件:print ("Hello World")然后执 ...查看全部


Hello World


学习任何一门语言,我想大家写的以一句就是hello world吧,下面我们来看看Python的hello world
创建一个hello.py的文件:
print ("Hello World")
然后执行命令:python hello.py ,输出
crh:Python crh$ python3 hello.py 
Hello World

 
Python执行过程为: 把代码读到内存 ---->词法语法分析 ---->放到编译器 ----> 生成字节码 ---->执行字节码 ---->生成机器码---->CPU执行,图示如下:
workfollow.png

指定解释器
在上面情况,我们指定Python3 来执行hello.py
如果想要类似于执行shell脚本一样执行python脚本,例: ./hello.py ,那么就需要在 hello.py 文件的头部指定解释器,如下:
crh:Python crh$ cat hello.py 
#!/usr/bin/env python3

print ("Hello World")
像上面这样,然后给hello.py文件添加执行权限(chmod +x hello.py)就可以像执行shell脚本一样./hello.py 即可。
***像上面是利用Linux env命令通过环境变量去找到你想用的Python命令,如果你指定用某个Python版本的话一可以写绝对路径,比如:/usr/bin/python or /usr/local/bin/python3
 
在交互器中执行
除了把程序写在文件里,还可以直接调用python自带的交互器运行代码,进行调试和测试
crh:Python crh$ python3
Python 3.5.1 (default, Dec 26 2015, 18:08:53)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
[quote]>> print ("Hello World")
Hello World
>>>
 


变量


在一个计算机程序中引用变量是用来存储信息和操作的。他们还提供一种标签数据与一个描述性的名称,所以我们的程序可以被读者和我们自己更清楚地理解。它有助于认为变量保存信息的容器。他们的唯一目的是标签和数据存储在内存中。这些数据可以通过使用程序引用。
 
声明变量
#_[i]_coding:utf-8_[/i]_

name = "Lucky chen"
如上面所示声明了一个变量name,他的值是"Lucky chen"
 
我们再来看一组连续赋值的过程:
>>> name = "crh"
>>> name1 = name
>>> print (name,name1)
crh crh
>>> name = "Lucky"
>>> print (name1,name)
crh Lucky
如上所示,为什么name1 = name 当后续把name变量的值改变了,为什么name1的值没有随着改变呢,如下看看你就明白了:
>>> name = "crh"     #首先在内存中打开一块内存空间存储name变量值
>>> id(name) #查看变量name的内存地址
4412833952
>>> name1 = name #把我们把name赋值给name1变量
>>> id(name1) #然后查看name1变量的内存地址 (跟name变量的内存地址一样)
4412833952
>>> name = "lucky" #重新打开一个内存空间存储name的变量值
>>> id(name) #查看新的name变量值的内存地址
4412834176
>>> id(name1) #查看name1变量内存地址
4412833952
如上所示,我们可以看出,nama1其实就是借助name变量做一个变量的赋值,通过name变量得到值所在内存中的内存地址后,从而变成了一个正常的赋值过程。而不换随着name变量的内存空间地址的改变而改变。示意图如下:
var.png


交互输入


用户输入就是程序和用户的交互,程序等待用户输入一个参数然后重新继续进行:
#!/usr/bin/env python3
#Authe: Lucky.chen
#_[i]_coding:utf-8_[/i]_

name = input("Please enter your name:")
print ("[size=16]#",name,"[/size]#")
input.png

如上图所示,默认Python3下的input函数用户输入的所有东西都当做字符串处理,所以你输入的年龄希望它是整数类型,还需要int()一下。
 
在python2中input这个函数,用户默认输入的是什么格式的参数,Python就当作是什么类型处理,Python2中获取用户输入参数的函数还有一个叫做raw_input(),这个函数默认也是字符串处理。可以看出Python3为了简洁统一,在Python3中已经不存在了raw_input()函数,input()一个函数完全可以做到所有使用。
 
平常如果我们用针对密码、密码串之类的交互的话,一般用户的输入时隐藏或者*****的,输入密码时,在Python下如果你需要你输入的东西不可见,可以利用getpass 模块中的 getpass方法来处理:
#!/usr/bin/env python3
#Authe: Lucky.chen
#_[i]_coding:utf-8_[/i]_[/quote]

#导入getpass模块
import getpass

# 将用户输入的内容赋值给 name 变量
pwd = getpass.getpass("请输入密码:")

# 打印输入的内容
print("Password is [size=16]",pwd,"***print end")[/size]

#比如我输入110119,执行过程和结果如下:
请输入密码:
Password is [size=16] 110119 ***print end
[/size]


注释和拼接


注释:
单行注释:# 开头就好,跟shell一样
多行注释:成对的三个单引号 ''' 注释内容 ''' 或者 成对的三个双引号 """  注释内容  """
>>> ''' My name is lucky ''' 
' My name is lucky '
[quote]>> """ My age is 23 """
' My age is 23 '
>>> # Good Idea
...
>>> msg = """ My info is :
... age: 23
... name: lucky
... job: IT"""
>>> print (msg)
My info is :
age: 23
name: lucky
job: IT
>>>
 
拼接:
1、难受的 "+" 
>>> name = "lucky"
>>> age = 23
>>> job = "IT"
>>>
>>> msg = """ Info of """ +name + """
... Name:""" +name + """
... Age:""" +age + """
... Job:""" +job
Traceback (most recent call last):
File "", line 4, in
TypeError: Can't convert 'int' object to str implicitly
>>>
>>> name = "lucky"
>>> age = "23"
>>> job = "IT"
>>> msg = """ Info of """ +name + """
... Name:""" +name + """
... Age:""" +age + """
... Job:""" +job
>>> print (msg)
Info of lucky
Name:lucky
Age:23
Job:IT
>>>
如上所示 "+"拼接只能是字符串,如果是整型、或者是浮点都会报错。
 
2、百分号(%)
 Code:
#!/usr/bin/env python3.5
#auther: lucky.chen[/quote]

name = input("Please input your name: ")
age = input("Please input your age:")
job = input("Please input your job:")
salary = input("Please input your salary:")

msg = """------------ info of %s
Name: %s
Age: %s
Job: %s
Salary: %s
""" % (name,name,age,job,salary)

print (msg)
Result:
Please input your name: lucky
Please input your age:23
Please input your job:IT
Please input your salary:40000
------------ info of lucky
Name: lucky
Age: 23
Job: IT
Salary: 40000

 3、使用format函数
情况一:使用变量格式化
Code:
#!/usr/bin/env python3.5
#auther: lucky.chen

name = input("Please input your name: ")
age = input("Please input your age:")
job = input("Please input your job:")
salary = input("Please input your salary:")

msg = """------------ info of {_Name}
Name: {_Name}
Age: {_Age}
Job: {_Job}
Salary: {_Salary}
""".format(_Name=name,_Age=age,_Job=job,_Salary=salary)

print (msg)
Result:
Please input your name: crh
Please input your age:23
Please input your job:IT
Please input your salary:45000
------------ info of crh
Name: crh
Age: 23
Job: IT
Salary: 45000
情况二:使用下脚标
#!/usr/bin/env python3.5
#auther: lucky.chen

name = input('please input your name:')
age = input('please input your age:')
job = input('please input your job:')
salary = input('please input your salary:')
msg = '''
------------info of {0}-----------
Name: {0}
Age: {1}
Job: {2}
Salary: {3}
'''.format(name,age,job,salary)
print (msg)
Result:
please input your name:chenronghua
please input your age:23
please input your job:OPS
please input your salary:50000

------------info of chenronghua-----------
Name: chenronghua
Age: 23
Job: OPS
Salary: 50000
format是比较好的方式,有时候我们必须使用format方法,所以掌握了format就好。
 


流程控制


一、流程控制这里先介绍 if ...... else  and if ...... elif ..... else 
 
1、if ..... else(用户认证登录)
Code:
#!/usr/bin/env python3.5
#auther: lucky.chen

name = input("Please input your name:")
passwd = input("Please input your password:")

if name == "crh" and passwd == "123456":
print (" \033[32mWelcome login OPS Management platform\033[0m ")
else:
print ("\033[31mYour UserName or Password Error\033[0m")
Result:
Please input your name:crh
Please input your password:34
Your UserName or Password Error

 2、if ..... elfi ...... else
Code:
#!/usr/bin/env python3.5
#auther: lucky.chen

age = int(input("Pleast input your age:"))

if age < 18:
print (" \033[32m You're too young \033[0m ")
elif age > 18 and age < 30:
print ("\033[31m You still have many chance comes at a time when youth waiting for you \033[0m")
else:
print ("\033[33m Before you is too old to do \033[0m")
Result:
Pleast input your age:23
You still have many chance comes at a time when youth waiting for you

 二、for 循环遍历
#!/usr/bin/env python3.5
#auther: lucky.chen

for num in range(5):
print ("loop is:",num)

# Result is:
loop is: 0
loop is: 1
loop is: 2
loop is: 3
loop is: 4
range函数也可以设置步长值,比如我们要打印出1-10中的所有偶数(默认步长为1)
#!/usr/bin/env python3.5
#auther: lucky.chen

for num in range(0,11,2):
print ("loop is:",num)

# Result
loop is: 0
loop is: 2
loop is: 4
loop is: 6
loop is: 8
loop is: 10
除掉range函数我们还可以使用xrange函数,为什么要这里要介绍xrange呢,因为xrange相对于range来说性能比较优越,因为xrange不需要一上来就开辟一块很大的内存空间,具体可以参考我之前发布的文章:Python中xrange和range的异同 ,但是好像Python3.*中没有了xrange函数。
 
for...else...循环介绍,不止if中有else,在for循环中也是可以用else的,在for循环中的else就是当前面的循环正常执行完后,没有跳出,后面的else代码将被执行。
crh:Python crh$ cat for.py 
#!/usr/bin/env python3
#Auther: lucky.chen

for num in range(4):
print ("Loop is:",num)
else:
print ("normal")
crh:Python crh$ ./for.py
Loop is: 0
Loop is: 1
Loop is: 2
Loop is: 3
normal
crh:Python crh$
crh:Python crh$ cat for.py 
#!/usr/bin/env python3
#Auther: lucky.chen

for num in range(4):
if num > 2:
break
print ("Loop is:",num)
else:
print ("normal")
crh:Python crh$ ./for.py
Loop is: 0
Loop is: 1
Loop is: 2
crh:Python crh$
三、while循环遍历
 
while 循环它的原理是:当条件为真的时候运行,当条件为假的时候停止!没有一个规定次数,不设置条件就永远循环下去。
#!/usr/bin/env python3.5
#auther: lucky.chen

import time
count = 0
while True:
count +=1
print ("loop",count)
time.sleep(3)
#这个循环3秒钟自+1后,无线循环只要这个条件为”真“,就无限循环下去
#!/usr/bin/env python3.5
#auther: lucky.chen

import time
num = 0

while num < 3:
num +=1
print ("Num is:",num)
time.sleep(3)

#这个循环每3秒循环一次,当条件num < 3的时候为真(自己设置的条件),当num不小于3的时候为假(false)循环停止.
While ...... else
#!/usr/bin/env python3.5
#auther: lucky.chen

while 1:
if num == 4:
print ("I think stop")
break
print (num)
num += 1
else:
print ("stop")

 四、break和continue介绍
break在循环中的作用是跳出所在的循环体,不在进行循环,而continue是跳出所在循环体中的本次循环,后续没有完的循环继续。
Code:
#!/usr/bin/env python3.5
#auther: lucky.chen

num = 1

print ("test break for loop start")
for n in range(5):
if n == num:
break
print (n)

print ("\n")

print ("test continue for loop start")
for n in range(5):
if n == num:
continue
print (n)
Result:
test break for loop start
0


test continue for loop start
0
2
3
4

猜数字游戏:
#!/usr/bin/env python3.5
#auther: lucky.chen

#load module (random)
import random

TryNum = 0
RandNum = random.randrange(10)
print (RandNum)


while TryNum < 3:
GuessNum = int(input("请猜测从0到9之间的一个中奖数字:"))

if GuessNum >= 10:
print ("你输入的数字不在中奖号码范围内,请重新输入!")
continue

if GuessNum == RandNum:
print ("恭喜你猜对了,你将获得小米电视一台!")
break

elif GuessNum > RandNum:
print ("你猜的数字太大了可以再往小了猜")

else:
print ("你猜的数字太小了可以往大了猜")

TryNum += 1

else:
print ("不好意思你三次机会用完了,Game over!")

#先随机到0-9中筛选出以为数字,然后用户三次机会猜测一个中奖号码,如果用户输入的数字不在范围内,则让用户再次输入.
Result:
4
请猜测从0到9之间的一个中奖数字:11
你输入的数字不在中奖号码范围内,请重新输入!
请猜测从0到9之间的一个中奖数字:11
你输入的数字不在中奖号码范围内,请重新输入!
请猜测从0到9之间的一个中奖数字:11
你输入的数字不在中奖号码范围内,请重新输入!
请猜测从0到9之间的一个中奖数字:11
你输入的数字不在中奖号码范围内,请重新输入!
请猜测从0到9之间的一个中奖数字:2
你猜的数字太小了可以往大了猜
请猜测从0到9之间的一个中奖数字:5
你猜的数字太大了可以再往小了猜
请猜测从0到9之间的一个中奖数字:4
恭喜你猜对了,你将获得小米电视一台!

 
五、嵌套循环
While for:
#!/usr/bin/env python3.5
#auther: lucky.chen

count = 1

while count < 4:
print("count var lt 4")

print ("#########################[size=16]#")[/size]

for n in range(3):
print ("for num is:",n)

print ("****************************")
count += 1
Result:
count var lt 4
#########################[size=16]#[/size]
for num is: 0
for num is: 1
for num is: 2
****************************
count var lt 4
#########################[size=16]#[/size]
for num is: 0
for num is: 1
for num is: 2
****************************
count var lt 4
#########################[size=16]#[/size]
for num is: 0
for num is: 1
for num is: 2
****************************

 死循环:
#!/usr/bin/env python3.5
#auther: lucky.chen
import time

while True:
print ("One Loop")
time.sleep(1)

while True:
print ("Two Loop")
time.sleep(1)

while True:
print ("Three Loop")
time.sleep(1)
#这是一个死循环,第一次执行这段code的时候,依次往下执行,单到了第三个while的时候,就一直是true,所以一直在执行第三个while下的code.

#结果如下:
One Loop
Two Loop
Three Loop
Three Loop
Three Loop
Three Loop
..........
..........
如上我们给出了一个死循环的例子,但是如果如果我们需要跳出循环应该怎么做,如果用break可以做到吗?
1、第一个while后加break分析
loop1.png

 
2、第二个while后加break分析
loop2.png

 
3、第三个while后加break分析
loop3.png

 
既然存在这种死循环的那我们有什么办法可以跳出呢?那就是打标志,标志位
Code:
#!/usr/bin/env python3.5
#auther: lucky.chen

count = 0
while True:
print ("我是第一层")
jump_1_flag = False

while True:
print ("我是第二层")
jump_2_flag = False

while True:
count += 1
print ("我是第三层")

if count > 3:
jump_2_flag = True
break

if jump_2_flag:
print ("第三层跳到我这里来了,我也要跳到第一层")
jump_1_flag = True
break

if jump_1_flag:
print ("第二层和第三层跳到第一层了,我也要跳")
break
分析和结果:
tags.png

开源分布式数据库Mysql中间件Mycat

开源项目 chris 发表了文章 1 个评论 4820 次浏览 2016-01-09 19:54 来自相关话题

什么是MYCAT []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存 ...查看全部


什么是MYCAT


    []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server[/][]结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品[/][]一个新颖的数据库中间件产品[/]

Mycat特性

    []支持SQL92标准[/][]遵守Mysql原生协议,跨语言,跨数据库的通用中间件代理。[/][]基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster。[/][]支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster[/][]基于Nio实现,有效管理线程,高并发问题。[/][]支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数。[/][]支持2表join,甚至基于caltlet的多表join。[/][]支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。[/][]支持多租户方案。[/][]支持分布式事务(弱xa)。[/][]支持全局序列号,解决分布式下的主键生成问题。[/][]分片规则丰富,插件化开发,易于扩展。[/][]强大的web,命令行监控。[/][]支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。[/][]支持密码加密[/][]支持IP白名单[/][]支持SQL黑名单、sql注入攻击拦截[/][]集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。[/]

Mycat架构

mycat_arch.png

Mycat高可用方案

mysql_ha1.png
mysql_ha2.png
mysql_ha3.png
mycat_ha4.png

Mycat监控

    []支持对Mycat、Mysql性能监控[/][]支持对Mycat的JVM内存提供监控服务[/][]支持对线程的监控[/][]支持对操作系统的CPU、内存、磁盘、网络的监控[/]
mycateye1.png
mycateye2.png

目标

低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。1.5版本架构
mycat2_0.png

长期规划2.0

    []完全实现分布式事务,完全的支持分布式。[/][]通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。[/][]通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。[/][]支持基于zookeeper的主从切换及Mycat集群化管理。[/][]通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。[/][]接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。[/][]通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。[/]


优势


基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。
MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。


Mycat关注


老外都开始关注Mycat了!
catmycat.png


Mycat官方论坛:http://i.mycat.io/forum.php
Mycat Github:https://github.com/MyCATApache
Mycat权威指南第一版_V1.5.1:http://pan.baidu.com/s/1i3SFOpf


Python input和raw_input的区别

编程艺术 空心菜 发表了文章 1 个评论 2223 次浏览 2015-12-14 23:18 来自相关话题

使用input和raw_input都可以读取控制台的输入,但是input和raw_input在处理数字时是有区别的 纯数字输入 当输入为纯数字时 []input返回的是数值类型,如int,floa ...查看全部
使用input和raw_input都可以读取控制台的输入,但是input和raw_input在处理数字时是有区别的


纯数字输入


当输入为纯数字时
    []input返回的是数值类型,如int,float[/][]raw_inpout返回的是字符串类型,string类型[/]

cb.png


输入字符串为表达式


input会计算在字符串中的数字表达式,而raw_input不会。
如输入 "57 + 3":
input会得到整数60
raw_input会得到字符串"57 + 3"
cb1.png

输入字符串结果如下:
cb3.png

通过上面的实验我们知道input它会根据用户输入变换相应的类型,而且如果要输入字符和字符串的时候必须要用引号包起来,而raw_input则是不管用户输入什么类型的都会转变成字符型.


python input的实现


python input的文档,你可以发现input其实是通过raw_input来实现的,原理很简单,就下面一行代码:
def input(prompt):
return (eval(raw_input(prompt)))

Python在生产环境都可以用来做什么?

编程艺术 koyo 回复了问题 2 人关注 3 个回复 4820 次浏览 2015-12-14 14:45 来自相关话题

为什么越来越多人喜欢全栈式开发语言 – Python

编程艺术 push 发表了文章 1 个评论 3820 次浏览 2015-11-29 20:12 来自相关话题

前段时间,ThoughtWorks在深圳举办一次社区活动上,有一个演讲主题叫做“Fullstack JavaScript”,是关于用JavaScript进行前端、服务器端,甚至数据库(MongoDB)开发,一个Web应用开发人员,只需要学会一门语言,就可以实现 ...查看全部
python_bigdata.png

前段时间,ThoughtWorks在深圳举办一次社区活动上,有一个演讲主题叫做“Fullstack JavaScript”,是关于用JavaScript进行前端、服务器端,甚至数据库(MongoDB)开发,一个Web应用开发人员,只需要学会一门语言,就可以实现整个应用。
 
受此启发,我发现Python可以称为大数据全栈式开发语言。因为Python在云基础设施,DevOps,大数据处理等领域都是炙手可热的语言。
bdlang.png

就像只要会JavaScript就可以写出完整的Web应用,只要会Python,就可以实现一个完整的大数据处理平台。


云基础设施


这年头,不支持云平台,不支持海量数据,不支持动态伸缩,根本不敢说自己是做大数据的,顶多也就敢跟人说是做商业智能(BI)。
 
云平台分为私有云和公有云。私有云平台如日中天的OpenStack,就是Python写的。曾经的追赶者CloudStack,在刚推出时大肆强调自己是Java写的,比Python有优势。结果,搬石砸脚,2015年初,CloudStack的发起人Citrix宣布加入OpenStack基金会,CloudStack眼看着就要寿终正寝。

如果嫌麻烦不想自己搭建私有云,用公有云,不论是AWS,GCE,Azure,还是阿里云,青云,在都提供了Python SDK,其中GCE只提供Python和JavaScript的SDK,而青云只提供Python SDK。可见各家云平台对Python的重视。

提到基础设施搭建,不得不提Hadoop,在今天,Hadoop因为其MapReduce数据处理速度不够快,已经不再作为大数据处理的首选,但是HDFS和Yarn——Hadoop的两个组件——倒是越来越受欢迎。Hadoop的开发语言是Java,没有官方提供Python支持,不过有很多第三方库封装了Hadoop的API接口(pydoop,hadoopy等等)。

Hadoop MapReduce的替代者,是号称快上100倍的Spark,其开发语言是Scala,但是提供了Scala,Java,Python的开发接口,想要讨好那么多用Python开发的数据科学家,不支持Python,真是说不过去。HDFS的替代品,比如GlusterFS,Ceph等,都是直接提供Python支持。Yarn的替代者,Mesos是C++实现,除C++外,提供了Java和Python的支持包。


DevOps


DevOps有个中文名字,叫做开发自运维。互联网时代,只有能够快速试验新想法,并在第一时间,安全、可靠的交付业务价值,才能保持竞争力。DevOps推崇的自动化构建/测试/部署,以及系统度量等技术实践,是互联网时代必不可少的。

自动化构建是因应用而易的,如果是Python应用,因为有setuptools, pip, virtualenv, tox, flake8等工具的存在,自动化构建非常简单。而且,因为几乎所有Linux系统都内置Python解释器,所以用Python做自动化,不需要系统预安装什么软件。

自动化测试方面,基于Python的Robot Framework企业级应用最喜欢的自动化测试框架,而且和语言无关。Cucumber也有很多支持者,Python对应的Lettuce可以做到完全一样的事情。Locust在自动化性能测试方面也开始受到越来越多的关注。

自动化配置管理工具,老牌的如Chef和Puppet,是Ruby开发,目前仍保持着强劲的势头。不过,新生代AnsibleSaltStack——均为Python开发——因为较前两者设计更为轻量化,受到越来越多开发这的欢迎,已经开始给前辈们制造了不少的压力。

在系统监控与度量方面,传统的Nagios逐渐没落,新贵如Sensu大受好评,云服务形式的New Relic已经成为创业公司的标配,这些都不是直接通过Python实现的,不过Python要接入这些工具,并不困难。

除了上述这些工具,基于Python,提供完整DevOps功能的PaaS平台,如CloudifyDeis,虽未成气候,但已经得到大量关注。 


网络爬虫


大数据的数据从哪里来?除了部分企业有能力自己产生大量的数据,大部分时候,是需要靠爬虫来抓取互联网数据来做分析。

网络爬虫是Python的传统强势领域,最流行的爬虫框架Scrapy,HTTP工具包urlib2,HTML解析工具beautifulsoup,XML解析器lxml,等等,都是能够独当一面的类库。

不过,网络爬虫并不仅仅是打开网页,解析HTML这么简单。高效的爬虫要能够支持大量灵活的并发操作,常常要能够同时几千甚至上万个网页同时抓取,传统的线程池方式资源浪费比较大,线程数上千之后系统资源基本上就全浪费在线程调度上了。Python由于能够很好的支持协程(Coroutine)操作,基于此发展起来很多并发库,如Gevent,Eventlet,还有Celery之类的分布式任务框架。被认为是比AMQP更高效的ZeroMQ也是最早就提供了Python版本。有了对高并发的支持,网络爬虫才真正可以达到大数据规模。

抓取下来的数据,需要做分词处理,Python在这方面也不逊色,著名的自然语言处理程序包NLTK,还有专门做中文分词的Jieba,都是做分词的利器。


数据处理


万事俱备,只欠东风。这东风,就是数据处理算法。从统计理论,到数据挖掘,机器学习,再到最近几年提出来的深度学习理论,数据科学正处于百花齐放的时代。数据科学家们都用什么编程?

如果是在理论研究领域,R语言也许是最受数据科学家欢迎的,但是R语言的问题也很明显,因为是统计学家们创建了R语言,所以其语法略显怪异。而且R语言要想实现大规模分布式系统,还需要很长一段时间的工程之路要走。所以很多公司使用R语言做原型试验,算法确定之后,再翻译成工程语言。

Python也是数据科学家最喜欢的语言之一。和R语言不同,Python本身就是一门工程性语言,数据科学家用Python实现的算法,可以直接用在产品中,这对于大数据初创公司节省成本是非常有帮助的。正式因为数据科学家对Python和R的热爱,Spark为了讨好数据科学家,对这两种语言提供了非常好的支持。

Python的数据处理相关类库非常多。高性能的科学计算类库NumPy和SciPy,给其他高级算法打了非常好的基础,matploglib让Python画图变得像Matlab一样简单。Scikit-learn和Milk实现了很多机器学习算法,基于这两个库实现的Pylearn2,是深度学习领域的重要成员。Theano利用GPU加速,实现了高性能数学符号计算和多维矩阵计算。当然,还有Pandas,一个在工程领域已经广泛使用的大数据处理类库,其DataFrame的设计借鉴自R语言,后来又启发了Spark项目实现了类似机制。

对了,还有iPython,这个工具如此有用,以至于我差点把他当成标准库而忘了介绍。iPython是一个交互式Python运行环境,能够实时看到每一段Python代码的结果。默认情况下,iPython运行在命令行,可以执行ipython notebook在网页中运行。用matplotlib绘制的图可以直接嵌入式的显示在iPython Notebook中。
iPython Notebook的笔记本文件可以共享给其他人,这样其他人就可以在自己的环境中重现你的工作成果;如果对方没有运行环境,还可以直接转换成HTML或者PDF。
ipython.png

为什么是Python

正是因为应用开发工程师、运维工程师、数据科学家都喜欢Python,才使得Python成为大数据系统的全栈式开发语言。

对于开发工程师而言,Python的优雅和简洁无疑是最大的吸引力,在Python交互式环境中,执行import this,读一读Python之禅,你就明白Python为什么如此吸引人。Python社区一直非常有活力,和NodeJS社区软件包爆炸式增长不同,Python的软件包增长速度一直比较稳定,同时软件包的质量也相对较高。有很多人诟病Python对于空格的要求过于苛刻,但正是因为这个要求,才使得Python在做大型项目时比其他语言有优势。OpenStack项目总共超过200万行代码,证明了这一点。

对于运维工程师而言,Python的最大优势在于,几乎所有Linux发行版都内置了Python解释器。Shell虽然功能强大,但毕竟语法不够优雅,写比较复杂的任务会很痛苦。用Python替代Shell,做一些复杂的任务,对运维人员来说,是一次解放。

对于数据科学家而言,Python简单又不失强大。和C/C++相比,不用做很多的底层工作,可以快速进行模型验证;和Java相比,Python语法简洁,表达能力强,同样的工作只需要1/3代码;和Matlab,Octave相比,Python的工程成熟度更高。不止一个编程大牛表达过,Python是最适合作为大学计算机科学编程课程使用的语言——MIT的计算机入门课程就是使用的Python——因为Python能够让人学到编程最重要的东西——如何解决问题。

顺便提一句,微软参加2015年PyCon,高调宣布提高Python在Windows上的编程体验,包括Visual Studio支持Python,优化Python的C扩展在Windows上的编译等等。脑补下未来Python作为Windows默认组件的场景。


内容来源:ThoughtWorks洞见
分享阅读:http://insights.thoughtworkers.org/full-stack-python/


Can't find PHP headers in /usr/include/php

智慧运维 空心菜 回复了问题 2 人关注 1 个回复 6654 次浏览 2015-07-26 13:50 来自相关话题

Python编码解析

编程艺术 空心菜 发表了文章 0 个评论 1879 次浏览 2016-09-09 17:38 来自相关话题

一般我们在Python2.7的环境进行Python的编程的时候,一般头部会加#-*- coding:utf-8 -*- ​来声明编码类型为utf-8的编码,那为什么要声明,一定要声明吗? 针对如上问题我们先来讨论另外一个问题,为什么我 ...查看全部
一般我们在Python2.7的环境进行Python的编程的时候,一般头部会加#-*- coding:utf-8 -*- ​来声明编码类型为utf-8的编码,那为什么要声明,一定要声明吗?

针对如上问题我们先来讨论另外一个问题,为什么我们可以在显示器上能看到这些文字、数字、图片、字符、等等信息呢?大家都知道计算机本身只能识别 0  1 的组合,他们是怎么展示这些内容的呢?我们怎么和计算机去沟通呢?

如果我们使用0 1 的组合和计算机沟通你还能看到这些内容吗?还有一个问题就是01的组合我相信对于常人类都是没有办法看懂的。

那怎么办?如何让计算机理解我们的语言,并且我们能理解计算机的语言呢?

举个比较形象的例子,中英文词典对照表,这样我们就可以把中英文进行互相的翻译了呢?对不对!同理计算机也是这样的他需要一个标准的对照关系,那么这个标准最早叫什么呢?ASCII表
ascii.gif

表格内容大致如下:
有特殊符号、大写字母、小写字母、数字(这里注意下0~9的数字是字符),在这些字符左边都有一个10进制的数字。但是对于10进制来说计算机他也是不能理解的,因为他只能理解0 1 ,但是10进制和2进制的转换就非常容易了!

举例来说:如果我在键盘上按一个A字母的时候那么实际是给计算机传输了一个数字65,通过这样的机制和计算机沟通,有了这个ASCII码表就可以和任何计算机进行沟通了。

这里在看个知识点:计算机中最小的单位是什么?bit   bit就咱们常说一位二进制,一位二进制要么是0 要么是 1

但是bit这个单位太小了,我们用字节(byte)来表示。他们是有换算的规则的(看下面的规则我想大家都不是很陌生对吧):
8b = 1B  #小b=bit ; 大B=byte
1024B = 1KB
1024KB = 1M
1024M = 1G
1024G = 1T
在存储英文的时候我们至少需要1个字节(一个字母),就是8位(bit),看下ASCII表中1个字节就可以表示所有的英文所需要的字符,是不非常高效!

为什么呢?早期的计算机的空间是非常宝贵的!

那你会发现1个字节8位,他能存储的最大数据是2的8次方-1 = 255,一个字节最多能表示255个字符 那西方国家他们使用了127个字符,那么剩下字符是做什么的呢?就是用来做扩展的,西方人考虑到还有其他国家。所以留下了扩展位。

但是呢有问题,计算机是西方人发明的,如果仅仅支持英文的话,这127个字符完全就可以表示所有英文中能用的的内容了。但是他没有考虑咱们大中国啊!ASCII到了中国之后发现:咱们中国最常用的中文都有6000多个完全不够用啊!

但是怎们办?中国人非常聪明:就在原有的扩展位中,扩展出自己的gbk、gb2312、gb2318字符编码。 

他是怎么扩展的呢?比如说在ASCII码中的128这个位置,这个位置又指定一张单独表,聪明吧! 其他国家也是这样设计的!

中国东亚大国是吧,我们国家比较NB,我要兼容其他国家的常用的编码!比如韩国日本,因为韩国和日本人家都有自己的编码,人家根本就不鸟你,举个例子来说,比如韩国的游戏,在中国下载安装之后会出现乱码的情况?什么鬼?

这种乱码的出现基本上就两种情况:
1、字符编码没有
2、字符编码冲突了,人家在写这个程序的时候指定的字符集和咱们使用的字符集的位置不对。 

你想想不光是亚洲国家这样,欧洲国家,非洲国家都会存在这个问题,基于这个乱象国际互联网组织就说你们各个国家都别搞了,我们给你们搞一个统一的,这个统一的是什么呢Unicode“万国编码”

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,规定虽有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536, 注:此处说的的是最少2个字节,可能更多。

这里还有个问题:使用的字节增加了,那么造成的直接影响就是使用的空间就直接翻倍了!举例还说:同样是ABCD这些字符存储一篇相同的文章,使用ASCII码如果是1M的话,那么Unicode存储至少2M可能还会更多。

为了解决个问题就出现了:UTF-8编码

UTF-8编码:是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存...

通过这种可扩展的方式来存储。

OK 上面了解了:
1、什么ASCII编码
2、什么Unicode编码
3、什么UTF-8编码

回顾下乱码的出现原因:1、没有字符集 2、字符集冲突

回过头来看下为什么需要在第二行加上指定编码呢?在2.x版本的Python中Pyton在解释.py文件的时候,默认是给他一个编码的就是ASCII码,so如果在2.7版本中如果你不指定编码并且在.py文件中写了一个ASCII码中没有的字符就会显示乱码 。

不过这个问题在Python3中就不存在了,因为在Python3中默认就是Unicode编码。


Python编码转换


有一个问题,既然有统一的Unicode编码了,为毛还需要编码转换?大家都统一一个编码不就可以了吗?

不要问我为什么,我问你们个问题,如果世界上出了一种世界语言,你会放弃中文吗?去使用这个世界通用语言吗?这就是个坑,是个遗留问题。

但是虽然以后可能世界语言会慢慢替代咱们常用的语言,大家以后沟通就使用世界语言就不会有沟通障碍了对吧。(就是举个例子)

还有一个情况是什么呢?韩国的游戏到中国来之后,是乱码?结合上一个回答咱们可以猜出:编写这个游戏的人在编写游戏的时候可能根本就没有考虑出口其他国家。那如果没有这个Unicode编码的话,到咱们这里来显示肯定是乱码是吧。

那就得需要通过转码把他们编码集,转换为Unicode(utf-8)编码集。这样他们就可以正常显示韩文了!(这里只是转编码集并不是翻译成中文不要弄混了~~!)

Python3中的编码转换
#在Python3中默认就是unicode编码
#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Author: Lucky.chen

tim = '华仔'
#转为UTF-8编码
print(tim.encode('UTF-8'))

#转为GBK编码
print(tim.encode('GBK'))

#转为ASCII编码(报错为什么?因为ASCII码表中没有‘华仔’这个字符集~~)
print(tim.encode('ASCII'))
EncodeError.png

 
二、Python2.X中的编码转换
#因为在python2.X中默认是ASCII编码,你在文件中指定编码为UTF-8,但是UTF-8如果你想转GBK的话是不能直接转,需要Unicode做一个中间人转换角色。
decode.png

#!/usr/bin/env python2
# _*_coding:utf-8_*_
# Author: Lucky.chen

import sys
print(sys.getdefaultencoding())


msg = "我爱北京天安门"
msg_gb2312 = msg.decode("utf-8").encode("gb2312")
gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk")

print(msg)
print(msg_gb2312)
print(gb2312_to_gbk)

Python3内置函数介绍

编程艺术 空心菜 发表了文章 0 个评论 1461 次浏览 2016-08-19 17:28 来自相关话题

详情参考:https://docs.python.org/3/library/functions.html​    1、abs(x)(返回一个数的绝对值) >>> abs(-12) 12 >>> ab ...查看全部
intfunc.png

详情参考:https://docs.python.org/3/library/functions.html​ 
 
1、abs(x)(返回一个数的绝对值)
>>> abs(-12)
12
>>> abs(-12.89)
12.89
>>> abs(-0.1)
0.1
 
2、all(iterable) 
all会循环括号内的每一个元素,如果括号内的所有元素都是真的,则返回True,如果有一个为假的那么就返回False
>>> all([0, 3])
False
>>> all([1, 3])
True
>>> all([1, ""])
False
一假则假,假的参数有:False、0、None、""、[]、()、{}等。
查看一个元素是否为假可以使用bool进行查看:
>>> bool("")
False
>>> bool(())
False
>>> bool(0)
False
>>> bool(1)
True

3、any(iterable)
循环元素,如果有一个元素为真,那么就返回真,一真则真。
>>> any([0, 1, 2, 3])
True
>>> any([{}, (), 0])
False

4、ascii(object)
在对象的类中寻找__repr__方法,获取返回值
 
 
>>> class Foo:
... def __repr_(self):
... return "Result"
...
>>> obj = Foo()
>>> r = ascii(obj)
>>> print(r)
<__main__.Foo object at 0x1045075c0>

5、bin(x)
将整数x转换为二进制字符串,如果x不为Python中int类型,x必须包含方法index()并且返回值为integer
 
# 返回一个整数的二进制
>>> bin(999)
'0b1111100111'
# 非整型的情况,必须包含__index__()方法切返回值为integer的类型
>>> class myType:
... def __index__(self):
... return 35
...
>>> myvar = myType()
>>> bin(myvar)
'0b100011'

6、bool([x])
查看一个元素的布尔值,非真即假
>>> bool([])
False
>>> bool(0)
False
>>> bool(1)
True

7、bytearray([source [, encoding [, errors]]])
bytearray([source [, encoding [, errors]]])返回一个byte数组。Bytearray类型是一个可变的序列,并且序列中的元素的取值范围为 [0 ,255]。
 
source参数:
  • 如果source为整数,则返回一个长度为source的初始化数组;
  • 如果source为字符串,则按照指定的encoding将字符串转换为字节序列;
  • 如果source为可迭代类型,则元素必须为[0 ,255]中的整数;
  • 如果source为与buffer接口一致的对象,则此对象也可以被用于初始化bytearray。

 
>>> bytearray(3)
bytearray(b'\x00\x00\x00')

8、bytes([source[, encoding[, errors]]])
>>> bytes("asdasd",encoding="utf-8")
b'asdasd'
返回一个bytes类型。
 
9、callable(object)
返回一个对象是否可以被执行
 
>>> def func():
... return 123
...
>>> callable(func)
True
>>> func = 123
>>> callable(func)
False

10、chr(i)
返回一个数字在ASCII编码中对应的字符,取值范围256个
>>> chr(66)
'B'
>>> chr(5)
'\x05'
>>> chr(55)
'7'
>>> chr(255)
'\xff'
>>> chr(25)
'\x19'
>>> chr(65)
'A'

11、compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
把字符串编译成python可执行的代码
 
>>> str = "for i in range(0,6): print(i)"
>>> c = compile(str, '', 'exec')
>>> exec(c)
0
1
2
3
4
5

 
12、complex([real[, imag]])
创建一个值为real + imag * j的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数
>>> complex(1, 2)
(1+2j)
# 数字
>>> complex(1)
(1+0j)
# 当做字符串处理
>>> complex("1")
(1+0j)
# 注意:这个地方在“+”号两边不能有空格,也就是不能写成"1 + 2j",应该是"1+2j",否则会报错
>>> complex("1+2j")
(1+2j)

13、dict(**kwarg)
创建一个数据类型为字典
 
>>> dic = dict({"k1":"123","k2":"456"})
>>> dic
{'k1': '123', 'k2': '456'}

14、dir([object])
返回一个类中的所有方法
 
>>> a = [1, 2, 3, 4]
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

15、divmod(a, b)
divmod(a,b)方法返回的是a//b(除法取整)以及a对b的余数,返回结果类型为tuple
 
 
>>> divmod(10, 3)
(3, 1)

16、enumerate(iterable, start=0)
遍历可迭代的数据类型,为元素生成下标
>>> a = [0, 1, 2, 3]
>>> for n, k in enumerate(a):
... print(n, k)
...
0 0
1 1
2 2
3 3

17、eval(expression, globals=None, locals=None)
把一个字符串当作一个表达式去执行
>>> string = "1 + 3"
>>> string
'1 + 3'
>>> eval(string)
4

 
18、exec(object[, globals[, locals]])
把字符串当作python代码执行
>>> exec("for n in range(5): print(n)")
0
1
2
3
4

19、filter(function, iterable)
筛选过滤,循环可迭代的对象,把迭代的对象当作函数的参数,如果符合条件就返回True,否则就返回False
>>> def func(x):
... if x == 11 or x == 22:
... return True
...
>>> ret = filter(func,[11,22,33,44])
>>> for n in ret:
... print(n)
...
11
22

20、float([x])
将整数和字符串转换成浮点数
>>> float("124")
124.0
>>> float("123.45")
123.45
>>> float("-123.34")
-123.34

 
21、format(value[, format_spec]) 
字符串格式化
>>> a = "My name is {0}, age is {1}".format('lucky', 18)
>>> print(a)
My name is lucky, age is 18

22、frozenset([iterable])
frozenset是冻结的集合,它是不可变的,存在哈希值,好处是它可以作为字典的key,也可以作为其它集合的元素。缺点是一旦创建便不能更改,没有add,remove方法。
 
23、globals()
获取当前scripts文件内的所有全局变量
 
>>> a = 3
>>> bsd = "54asd"
>>> globals()
{'__doc__': None, 'bsd': '54asd', '__package__': None, 'a': 3, '__spec__': None, '__builtins__': , '__name__': '__main__', '__loader__': }

24、hash(object)
返回一个对象的hash值
 
>>> a = "asdadasdwqeq234sdfdf"
>>> hash(a)
5390438057823015497

25、help([object])
查看一个类的所有详细方法
 
>>> help(list)
Help on class list in module __builtin__:

class list(object)
| list() -> new empty list
| list(iterable) -> new list initialized from iterable's items
|
| Methods defined here:
|
| __add__(...)
| x.__add__(y) <==> x+y
|
| __contains__(...)
| x.__contains__(y) <==> y in x
|
| __delitem__(...)
| x.__delitem__(y) <==> del x[y]
|
| __delslice__(...)
| x.__delslice__(i, j) <==> del x[i:j]
|
| Use of negative indices is not supported.
..........

26、hex(x)
获取一个数的十六进制
 
>>> hex(13)
'0xd'

27、id(object)
返回一个对象的内存地址
>>> a = 123
>>> id(a)
1835400816

28、input([prompt])
交互式输入
 
 
29、int(x, base=10)
获取一个数的十进制
>>> int("31")
31

30、isinstance(object, classinfo)
判断对象是否是这个类创建的
 
>>> li = [11,22,33]
>>> isinstance(li,list)
True

31、issubclass(class, classinfo)
查看一个对象是否为子类
 
32、iter(object[, sentinel])
创建一个可迭代的对象
>>> obj = iter([11,22,33,44])
>>> obj

>>> for n in obj:
... print(n)
...
11
22
33
44

 
33、len(s)
查看一个对象的长度
 
>>> name = 'lucky'
>>> len(name)
5

34、list([iterable])
创建一个数据类型为列表
>>> li = list([11,22,33,44])
>>> li
[11, 22, 33, 44]

35、locals()
返回当前scripts的局部变量,返回结果为字典格式
>>> def func():
... name="lucky"
... print(locals())
...
>>> func()
{'name': 'lucky'}

 
 
36、map(function, iterable, …)
把可迭代的对象作为函数的值
 
>>> ret = map(lambda x: x + 100, [1, 2, 3, 4, 5])
>>> for n in ret:
... print(n)
...
101
102
103
104
105

37、max(iterable, *[, key, default]) max(arg1, arg2, *args[, key])
获取一个对象中的最大值
 
>>> li = [1, 3, 5, 9 ,3]
>>> max(li)
9

38、min(iterable, *[, key, default])  min(arg1, arg2, *args[, key])
获取一个对象中的最小值
>>> li = list([11,22,33,44])
>>> li = [11,22,33,44]
>>> min(li)
11

39、next(iterator[, default])
 
每次只拿取可迭代对象的一个元素
 
>>> obj = iter([11,22,33,44])
>>> next(obj)
11
>>> next(obj)
22
>>> next(obj)
33
>>> next(obj)
44
>>> next(obj)
# 如果没有可迭代的元素了就会报错
Traceback (most recent call last):
File "", line 1, in
StopIteration

40、oct(x)
获取一个字符串的八进制
>>> oct(13)
'0o15'

41、open(file, mode=’r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
文件操作的函数,用来做文件操作的
 
 
 
42、ord(c)
把一个字母转换为ASCII对对应表中的数字
 
>>> ord("a")
97
>>> ord("t")
116

43、pow(x, y[, z])
返回一个数的N次方
>>> pow(2, 10)
1024
>>> pow(2, 20)
1048576

 
44、print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)
打印输出
 
 
45、range(start, stop[, step])
生成一个可迭代序列
 
>>> range(10)
range(0, 10)
>>> for n in range(5):
... print(n)
...
0
1
2
3
4

46、reversed(seq)
对一个对象的元素进行反转
>>> li = [1, 2, 3, 4]
>>> reversed(li)

>>> for n in reversed(li):
... print(n)
...
4
3
2
1

47、round(number[, ndigits])
四舍五入
>>> round(3.3)
3
>>> round(3.7)
4

48、set([iterable])
创建一个数据类型为集合
>>> varss = set([11,222,333])
>>> type(varss)

49、slice(start, stop[, step])
元素的切片操作都是调用的这个方法
 
50、sorted(iterable[, key][, reverse])
为一个对象的元素进行排序
 
>>> li = [ 2, 3, 4, 9, 1, 100]
>>> sorted(li)
[1, 2, 3, 4, 9, 100]

51、sum(iterable[, start])
求和
>>> sum([11,22,33])
66

52、type(object)
查看一个对象的数据类型
 
>>> a = 1
>>> type(a)

>>> a = "str"
>>> type(a)

53、vars([object])
查看一个对象里面有多少个变量
 
54、zip(*iterables)
联合迭代
>>> li1 = ["k1","k2","k3"]
>>> li2 = ["a","b","c"]
>>> zip(li1,li2)

>>> dic = zip(li1,li2)
>>> for n in dic:
... print(n)
...
('k1', 'a')
('k2', 'b')
('k3', 'c')

55、import(name, globals=None, locals=None, fromlist=(), level=0)
导入模块,把导入的模块作为一个别名。
生成一个六位的随机验证码,且包含数字,数字的位置随机:
# 导入random模块
import random
temp = ""
for i in range(6):
num = random.randrange(0,4)
if num == 3 or num == 1:
rad2 = random.randrange(0,10)
temp = temp + str(rad2)
else:
rad1 = random.randrange(65,91)
c1 = chr(rad1)
temp = temp + c1
print(temp)

Python装饰器详解

编程艺术 空心菜 发表了文章 0 个评论 1621 次浏览 2016-08-18 23:11 来自相关话题

装饰器 定义:本质就是函数,(装饰其他函数)就是为其他函数添加额外的功能; 遵循的原则:1、不能修改其被装饰函数的源代码    2、不能修改其被装饰函数的调用方式   实现装饰器需要用到的知识点: ...查看全部


装饰器


定义:本质就是函数,(装饰其他函数)就是为其他函数添加额外的功能;
遵循的原则:1、不能修改其被装饰函数的源代码    2、不能修改其被装饰函数的调用方式
 
实现装饰器需要用到的知识点:
  1. 函数即"变量"
  2. 高阶函数
  3. 嵌套函数

如果你对装饰器实现的如上三个知识点理解了的话,那你就完全可以理解装饰器了,图示如下:
Decorator.png

下面我们就把装饰器的知识分解一个一个来理解。
 
1、函数即"变量"
让我们来看一下几个例子,来说明函数即变量
函数的错误调用案例,跟变量一样,还没有定义就调用:
# 错误调用方式一:
def foo():
print('in the foo!')
bar()

foo()
# 输出
NameError: name 'bar' is not defined (因为在调用foo函数执行的时候函数体内又调用了bar函数,但是bar函数并没有定义)

# 错误调用方式二:
def foo():
print('in the foo!')
bar()

foo()

def bar():
print('in the bar!')

# 输出
NameError: name 'bar' is not defined (同上面,不同的是虽然你在下面定义了bar函数,但是在调用之后才定义的.)
从上面的例子可以看出,函数的定义和调用,其实是跟变量是一样的,变量在没有定义之前你对变量进行操作也是会报变量没有被定义的错误。
 
正确的调用方式如下:
# 错误调用方式二:
def foo():
print('in the foo!')
bar()

def bar():
print('in the bar!')

foo()

# 输出
in the foo!
in the bar!
具体说明我们可以结合定义变量图示说明,我们把整个内存看作是一个大楼,把变量看做是门牌号,而变量真正存在的值看做是房间里面的东西,房间就相当于是大内存中的一小块内存块,图示如下:
funcvar.png

如图所示我们可以看出函数def下定义的函数名就相当于变量的变量名,而函数体就相当于变量的值;所以函数的执行跟调用变量是一样的,只有在你执行之前所有的函数已经声明,占用了内存地址才可以执行,否则在你执行之前未定义,而会报错。
 
函数和变量一样,如果你已经定义好了,就会从内存中划分出一块内存空间存储进行存储,那什么时候回收这个内存空间呢?1、当你整个程序执行完成后,你所定义的变量或者函数占用的内存空间就会被释放  2、就是你利用del()内置函数的删除方法,把变量名和函数名删除,然后Python的内存回收机制发现这块内存空间没有被引用了,就把这块没有被引用的内存空间回收了。
 
2、高阶函数
高阶函数定义:
  1. 把一个函数名当做实参传给另外一个函数当做形参
  2. 返回值(return)中包含函数名

只要满足以上其中一个条件就称为高阶函数。
 
首先我们看一个高阶函数的例子:
def foo(func):
print('in the foo!')
print(func)
func()


def bar():
print('in the bar!')

foo(bar)

结果:
in the foo!
# 打印了函数bar的内存地址
in the bar!
如上是一个符号传递函数名的一个高阶函数的例子。
 
下面我们利用高阶函数来做一个不改变被装饰函数代码,为被装饰函数添加一个新功能,我们这里添加一个程序运行时间的功能。
 
把一个函数名当做实参传给另外一个函数(没有改变函数的代码,添加了一个功能,但是运行方法改变了)
import time
def foo(func):
print('in the foo!')
start_time = time.time()
func()
stop_time = time.time()
print("func run time is %s" % (stop_time - start_time))


def bar():
time.sleep(2)
print('in the bar!')

foo(bar)

# 结果如下:
in the foo!
in the bar!
func run time is 2.002309799194336
如上代码把bar函数当做一个实参,传给了foo函数当做形参,然后在里面运行了bar函数。
 
返回值中包含函数(虽然没有改变函数运行方式,但是好像功能没有加上)
import time
def foo(func):
print(func)
return func


def bar():
time.sleep(2)
print('in the bar!')

bar = foo(bar)
bar()

# 结果为:

in the bar!
好像都并没有什么卵用,但是你应该发现了,我可以做到不改变函数调用方式和增加功能,但是单独利用高阶函数,这两个条件同事满足是做不到的,因为还需要结合嵌套函数才行。
 
3、嵌套函数
定义:在一个函数体内创建另外一个函数,这种函数就叫内嵌函数(基于python支持静态嵌套域)
 
函数嵌套示范:
def foo():
print('in the foo')
def bar():
print('in the bar')

bar()

foo()
这就是一个最简单的一个嵌套函数,一个函数下,再定义另外一个函数。
 
局部作用域和全局作用域的访问顺序:
x = 0
def grandpa():
x = 1
def dad():
x = 2
def son():
x = 3
print(x) # 打印出来为3
son()
dad()
grandpa()

print(x) # 这个还是0
结果是 3, 0,过程如图所示:
sorted.png

 
闭包:
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是 closure
def counter(start_num=0):
count=[start_num]
def incr():
count[0]+=1
return count[0]
return incr

print(counter())
print(counter()())
print(counter()())

c=counter()
print(c())
print(c())
没看懂,先记录一下。
 
4、装饰器
讲了装饰器 = 高阶函数 + 嵌套函数,还是添加一个打印程序执行时间功能,例子如下:
import time
def timer(func):
print("in the timer")
def foo():
start_time = time.time()
func()
stop_time = time.time()
print("fun run time is %s" % (stop_time - start_time))
return foo


def bar():
time.sleep(2)
print('in the bar')

bar = timer(bar)
bar()

# 结果

in the timer
in the bar
fun run time is 2.004901885986328
如上代码所示,我们为了给bar函数增加一个计算他运行时间的功能,我们既没有改变他的运行方式bar(),也没有改变他的内部代码,功能,也实现了,这就是利用高阶函数 + 嵌套函数完成的一个简易版的装饰器,在python中为了简化方法,装饰函数可以直接利用@符号把装饰函数应用到被装饰函数的上,如下所示:
import time
def timer(func):
print("in the timer")
def foo():
start_time = time.time()
func()
stop_time = time.time()
print("fun run time is %s" % (stop_time - start_time))
return foo

@timer # @timer 相当于 bar = timer(bar)
def bar():
time.sleep(2)
print('in the bar')

# bar = timer(bar)
bar()

# 结果如下:
in the timer
in the bar
fun run time is 2.000408887863159
如上可以看出来,结果是一样的,简易版的装饰器我们可以做出来了,那下面我们在深入一下,做一个高级版本的装饰器,那我们在熟悉如下几个知识点。
 
1、函数参数固定
def decor(func):
def wrapper(n):
print('starting')
func(n)
print('stopping')
return wrapper


def test(n):
print('in the test arg is %s' % n)

decor(test)('lucky')
分解过程:
argsfun.png

其实就是 decor(test)('lucky')   的过程你可以理解为  a = decor(test) = wrapper  然后在调用  a('lucky') = wrapper('lucky') 。
 
2、函数参数不固定
def decor(func):
def wrapper(*args, **kwargs):
print('starting')
func(*args, **kwargs)
print('stopping')
return wrapper


def test(n, x=1):
print('in the test n is %s, x is %s' % (n, x))

decor(test)('alex', x=2)

# 结果如下:
starting
in the test n is alex, x is 2
stopping

3、无参装饰器
import time
def decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
stop = time.time()
print('run time is %s ' % (stop - start))
print('timeout')
return wrapper

@decorator
def test(list_test):
for i in list_test:
time.sleep(0.1)
print('-' * 20, i)

#decorator(test)(range(10))
test(range(10))

4、带参数的装饰器
import time
def timer(timeout=0):
def decorator(func):
def wrapper(*args, **kwargs):
start=time.time()
func(*args, **kwargs)
stop=time.time()
print('run time is %s ' %(stop-start))
print(timeout)
return wrapper
return decorator

@timer(2)
def test(list_test):
for i in list_test:
time.sleep(0.1)
print('-'*20, i)

# timer(timeout=2)(test)(range(10)) timer(timeout=2) = decorator timer(timeout=2)(test) = decorator(test) = wrapper
# timer(timeout=2)(test)(range(10)) = decorator(test)(range(10)) = wrapper(range(10))
test(range(10))

高级版装饰器:
user, passwd = 'lucky', 'abc123'

def auth(auth_type):
print("auth func:", auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print("wrapper func args:", *args, **kwargs)
if auth_type == "local":
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32mUser has passwed authentication\033[0m")
res = func(*args, **kwargs) # from home
print("---after authenticaion")
return res
else:
exit("\033[31mInvalid username or passwd\033[0m")
elif auth_type == "ldap":
print("\033[33m不会ldap,搞毛线啊!\033[0m")
return wrapper
return outer_wrapper

@auth(auth_type="ldap")
def bbs():
print("welcome to bbs page")

@auth(auth_type="local") # home = wrapper()
def home():
print("welcome to home page")
return "from home"

bbs()
home()

装饰器的应用:
装饰器功能:函数超时则终止
# -*- coding: utf-8 -*-  
from threading import Thread
import time

class TimeoutException(Exception):
pass

ThreadStop = Thread._Thread__stop#获取私有函数

def timelimited(timeout):
def decorator(function):
def decorator2(*args,**kwargs):
class TimeLimited(Thread):
def __init__(self,_error= None,):
Thread.__init__(self)
self._error = _error

def run(self):
try:
self.result = function(*args,**kwargs)
except Exception,e:
self._error =e

def _stop(self):
if self.isAlive():
ThreadStop(self)

t = TimeLimited()
t.start()
t.join(timeout)

if isinstance(t._error,TimeoutException):
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))

if t.isAlive():
t._stop()
raise TimeoutException('timeout for %s' % (repr(function)))

if t._error is None:
return t.result

return decorator2
return decorator

@timelimited(2)
def fn_1(secs):
time.sleep(secs)
return 'Finished'

if __name__ == "__main__":
print fn_1(4)

Python三元计算和深浅拷贝

编程艺术 空心菜 发表了文章 0 个评论 1251 次浏览 2016-08-17 21:54 来自相关话题

三元计算 三元计算也称为三目计算,如名字表示的三元运算符需要三个操作数,语法为: 条件表达式?表达式1:表达式2。 or var = 值1 if 条件 else 值2 说明:问号前面的位置是判 ...查看全部


三元计算


三元计算也称为三目计算,如名字表示的三元运算符需要三个操作数,语法为:
条件表达式?表达式1:表达式2。  or  
var = 值1 if 条件 else 值2
说明:问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。
其逻辑为:如果为真执行第一个,否则执行第二个。
例子:
>>> a = 'xxoo'

>>> Re = 'xx' if a == 'xxoo' else 'oo'
>>> print(Re)
xx

>>> a = 'xx'
>>> Re = 'xx' if a == 'xxoo' else 'oo'
>>> print(Re)
oo
如上结果你可以看成是如下代码的简写的例子:
a = 'xxoo'
if a == 'xxoo':
Re = 'xx'
else:
Re = 'oo'
这样我想你就知道了!
 


深浅拷贝


深浅拷贝分为两部分,一部分是数字和字符串另一部分是列表、元组、字典等其他数据类型。
 
数字和字符串:
对于数字和字符串而言,赋值、浅拷贝和深拷贝无意义,因为他们的值永远都会指向同一个内存地址,他们就是内存地址的复用。
>>> import copy      # 导入内置copy模块
>>> name = 'lucky' # 命名name变量
>>> id(name) # 查看name变量的内存地址
4426658624
>>>
>>> name1 = name # 赋值应用变量 name1
>>> id(name1) # 查看变量name1内存地址
4426658624
>>>
>>> name2 = copy.copy(name) # 浅copy name变量赋值给name2变量
>>> id(name2) # 查看name2变量内存地址
4426658624
>>>
>>> name3 = copy.deepcopy(name) # 深copy name变量复制给name2变量
>>> id(name3) # 查看name3变量的内存地址
4426658624
>>>
>>> print(name, name1, name2, name3) # 打印四个变量的值
lucky lucky lucky lucky
如上结果可以看出,不管是直接引用还是深浅copy其最后的结果变量的内存地址都没有变,只是定义的方法不一样,如下图示:
strcopy.png

 
其他数据类型:
对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,内存地址可能会发生相应的变化。
1、赋值
>>> num1 = {'n1': 1, 'n2': 2, 'n3': [3, 4]}
>>> num2 = num1
>>> print(id(num1), id(num2))
4424864840 4424864840
>>>
>>> num1['n1'] = 7
>>> print(id(num1), id(num2))
4424864840 4424864840
>>> print(num1, num2)
{'n2': 2, 'n3': [3, 4], 'n1': 7} {'n2': 2, 'n3': [3, 4], 'n1': 7}
>>>
>>> num1['n3'][0] = 9
>>> print(id(num1), id(num2))
4424864840 4424864840
>>> print(num1, num2)
{'n2': 2, 'n3': [9, 4], 'n1': 7} {'n2': 2, 'n3': [9, 4], 'n1': 7}

如上所示,不管怎么改变原始的info字典内容,哪怕是改变里面的列表元素值,而info2的内容随之变化,运维他们的引用的内存地址是一样的,图示如下:
fuzhi.png

 
2、浅拷贝
 
浅拷贝,在内存中只额外创建第一层数据,里面则是完全复制。
>>> num1 = {'n1': 1, 'n2': 2, 'n3': [3, 4]}
>>> num2 = num1.copy()
>>> print(id(num1), id(num2))
4426663432 4426602824

>>> print(id(num1['n1']), id(num2['n1']))
4423026704 4423026704
>>> print(id(num1['n3']), id(num2['n3']))
4427044168 4427044168
>>> print(id(num1['n3'][0]), id(num2['n3'][0]))
4423026768 4423026768
>>> num1['n3'][0] = 9
>>> print(id(num1), id(num2))
4426663432 4426602824
>>> print(num1, num2)
{'n2': 2, 'n3': [9, 4], 'n1': 1} {'n2': 2, 'n3': [9, 4], 'n1': 1}
>>> num1['n1'] = 19
>>> print(num1, num2)
{'n2': 2, 'n3': [9, 4], 'n1': 19} {'n2': 2, 'n3': [9, 4], 'n1': 1}
>>> print(id(num1['n3'][0]), id(num2['n3'][0]))
4423026960 4423026960

浅copy也可以利用copy模块 num2 = copy.copy(num1)
 图示如下:
ashcopy.png

 
3、深拷贝
深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)
 
>>> num1 = {'n1': 1, 'n2': 2, 'n3': [3, 4]}
>>> num2 = copy.deepcopy(num1)
>>> print(id(num1), id(num2))
4424864840 4427043656
>>> print(id(num1['n1']), id(num2['n1']))
4423026704 4423026704
>>> print(id(num1['n3']), id(num2['n3']))
4427043592 4426939976
>>> num1['n1'] = 9
>>> print(id(num1['n1']), id(num2['n1']))
4423026960 4423026704
从上面来看,深copy内存地址则完全不一样,图示如下:
deepcopy.png
编程世界、编码色彩!