在使用Python在各种UNIX(Linux,FreeBSD和MacOS X)下处理命名管道(FIFO)时,我注意到了一些奇怪的事情.第一个,也许是最烦人的是尝试打开空闲/空闲FIFO只读将被阻止(除非我使用os.O_NONBLOCK
较低级别的os.open()
调用).但是,如果我打开它进行读/写,那么我就不会阻塞.
例子:
f = open('./myfifo', 'r') # Blocks unless data is already in the pipe
f = os.open('./myfifo', os.O_RDONLY) # ditto
# Contrast to:
f = open('./myfifo', 'w+') # does NOT block
f = os.open('./myfifo', os.O_RDWR) # ditto
f = os.open('./myfifo', os.O_RDONLY|os.O_NONBLOCK) # ditto
Run Code Online (Sandbox Code Playgroud)
我只是好奇为什么.为什么打开调用块而不是后续的一些读操作?
另外我注意到非阻塞文件描述符可以表现为Python中的不同行为.在我使用的情况下os.open()
与os.O_NONBLOCK
初始开启操作那么os.read()
似乎如果数据还没有准备好文件描述符返回一个空字符串.但是,如果我使用fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK)
然后os.read
引发异常(errno.EWOULDBLOCK
)
是否有一些其他标志open()
由我的os.open()
例子未设置的法线设置?它们有什么不同,为什么?
是否有在Python中实现的GoF Observer的示例性示例?我有一些代码,当前有一些调试代码通过密钥类(如果设置了魔法env,当前生成消息给stderr).此外,该类还有一个接口,用于递增返回结果以及存储它们(在内存中)以进行后期处理.(该类本身是一个作业管理器,用于通过ssh在远程机器上同时执行命令).
目前该类的用法类似于:
job = SSHJobMan(hostlist, cmd)
job.start()
while not job.done():
for each in job.poll():
incrementally_process(job.results[each])
time.sleep(0.2) # or other more useful work
post_process(job.results)
Run Code Online (Sandbox Code Playgroud)
一个易用的使用模型是:
job = SSHJobMan(hostlist, cmd)
job.wait() # implicitly performs a start()
process(job.results)
Run Code Online (Sandbox Code Playgroud)
这一切都适用于当前的实用程序.但它确实缺乏灵活性.例如,我目前支持简短的输出格式或进度条作为增量结果,我还支持该post_process()
功能的简短,完整和"合并消息"输出.
但是,我想支持多个结果/输出流(到终端的进度条,对日志文件的调试和警告,从成功作业到一个文件/目录的输出,错误消息以及从非成功作业到另一个作业的其他结果)等).
这听起来像是一个需要Observer的情况......我的类的实例接受来自其他对象的注册,并在发生时使用特定类型的事件回调它们.
我正在看PyPubSub,因为我在SO相关问题中看到了几个引用.我不确定我是否已经准备好将外部依赖项添加到我的实用程序中,但是我可以看到使用它们的接口作为我的模型的价值,如果这将使其他人更容易使用它.(该项目既可以作为独立的命令行实用程序,也可以作为编写其他脚本/实用程序的类).
总之,我知道如何做我想要的......但是有很多方法可以实现它.从长远来看,我想知道最有可能为代码的其他用户工作的建议.
代码本身位于:classh.
我一直在重构一些相当苛刻的代码,并遇到了以下相当奇怪的构造:
#!/usr/bin/env python2.7
# ...
if (opts.foo or opts.bar or opts.baz) is None:
# (actual option names changed to protect the guilty)
sys.stderr.write("Some error messages that these are required arguments")
Run Code Online (Sandbox Code Playgroud)
......我想知道这是否会产生任何可想象的感觉.
我将其更改为:
#!/usr/bin/env python2.7
if None in (opts.foo, opts.bar, opts.baz):
# ...
Run Code Online (Sandbox Code Playgroud)
我确实启动了一个解释器并实际尝试了第一个构造......只有当值全部为假并且这些错误值的最后一个为None时,它才会起作用.(换句话说,CPython的实现似乎从一个或多个表达式返回第一个真值或最后一个假值).
我仍然怀疑正确的代码应该使用添加了2.5 的any()或all()内置函数(有问题的代码已经需要2.7).我还不确定哪个是首选的/预期的语义,因为我刚开始这个项目.
那么这个原始代码是否有意义呢?
我一直在尝试在MacOS X 10.9.5和Python 2.7.9下使用Python-LDAP(版本2.4.19)
我想在调用之后验证我与给定LDAP服务器的连接.start_tls_s()
(或者如果无法验证证书则使方法引发和异常).(我也想检查CRL,但这是另一回事).
这是我的代码:
#!python
#!/usr/bin/env python
import ConfigParser, os, sys
import ldap
CACERTFILE='./ca_ldap.bad'
## CACERTFILE='./ca_ldap.crt'
config = ConfigParser.ConfigParser()
config.read(os.path.expanduser('~/.ssh/creds.ini'))
uid = config.get('LDAP', 'uid')
pwd = config.get('LDAP', 'pwd')
svr = config.get('LDAP', 'svr')
bdn = config.get('LDAP', 'bdn')
ld = ldap.initialize(svr)
ld.protocol_version=ldap.VERSION3
ld.set_option(ldap.OPT_DEBUG_LEVEL, 255 )
ld.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
ld.set_option(ldap.OPT_X_TLS_CACERTFILE, CACERTFILE)
ld.set_option(ldap.OPT_X_TLS_DEMAND, True )
ld.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
## From: https://stackoverflow.com/a/7810308/149076
## and : http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Demo/initialize.py?revision=1.14&view=markup
ld.start_tls_s()
for each in dir(ldap):
if 'OPT_X_TLS' in each:
try:
print '\t*** %s: %s' % …
Run Code Online (Sandbox Code Playgroud) 我只是想了解 Redis/Lua 脚本,我想知道是否有人发现以下代码有问题。
这是我尝试实现非常简单的“CAS”语义:用一个键和两个参数调用它。它将检查服务器上与该键关联的值是否以第一个参数开头,如果是,则将键的新值设置为第二个参数并返回 1,否则返回 0;如果键与字符串以外的某种类型的数据相关联,那么 Redis 将返回并出错,就像您尝试对此类键/值组合执行 SET 命令一样。如果键在调用之前不存在,则该函数将返回 0(失败)。
这是脚本:
local x=string.len(ARGV[1]);
if redis.call('GETRANGE', KEYS[1], 0, x-1) == ARGV[1] then
redis.call('SET', KEYS[1], ARGV[2]);
return 1;
end;
return 0
Run Code Online (Sandbox Code Playgroud)
以下是在前缀值为“bar”的键“foo”上调用脚本的示例(在redis-cli 中):
eval "local x=string.len(ARGV[1]); if redis.call('GETRANGE', KEYS[1], 0, x-1) == ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]); return 1; end; return 0" 1 foo bar barbazzle
Run Code Online (Sandbox Code Playgroud)
我认为这种使用模式可能是您想要同时存储“围栏令牌”和带有键的值的情况……如果并发客户端持有正确的围栏令牌,则允许并发客户端尝试更新该值。
这看起来像是一种安全的使用模式来代替 WATCH/MULTI/EXEC 语义吗?(似乎您可以获取当前值,在您的本地代码中拆分 fencing 令牌,构建一个新值,然后尝试使用似乎比 WATCH/MULTI/EXEC 调用更容易混淆的语义随时更新密钥)。
(我知道我的脚本的语义与memcached CAS 命令略有不同;这是故意的)。
这确实通过了我有限的测试......所以我真的在询问任何潜在的并发/原子性问题,以及 Lua 中是否有任何愚蠢的东西——因为我过去几乎没有接触过 Lua)。
我正在设置一个简单的SQLite数据库来通过Python访问.到目前为止,我有一个基本表和几个触发器 - 我希望在添加新记录时有一个触发器更新字段列'date_added',而另一个触发器在稍后更新记录时更新列'date_updated' .这是我的触发器的SQLite语法:
CREATE TRIGGER add_contact AFTER INSERT ON contact_info
BEGIN
UPDATE contact_info SET date_added = DATETIME('NOW') WHERE pkid = new.pkid;
END;
CREATE TRIGGER update_contact AFTER UPDATE ON contact_info
BEGIN
UPDATE contact_info SET date_updated = DATETIME('NOW') WHERE pkid = new.pkid;
END;
Run Code Online (Sandbox Code Playgroud)
'add_contact'触发器似乎工作正常......当我按计划通过sql INSERT命令添加新记录时它会触发.
问题似乎是'update_contact'触发器......当我通过sql UPDATE命令(按计划)更新记录时,以及当我添加新记录时,它都会触发:
即当我添加新记录时,我会在'date_added'和'date_updated'列中得到这个:
2010-07-12 05:00:06|2010-07-12 05:00:06
Run Code Online (Sandbox Code Playgroud)
当我更新该记录时,它会像这样改变:
2010-07-12 05:00:06|2010-07-12 05:14:26
Run Code Online (Sandbox Code Playgroud)
我想我不知道为什么UPDATE触发器也会在INSERT上触发?
TIA,
蒙特
编辑添加:有关如何使其按预期工作的任何提示?
我一直在阅读关闭表作为一种在SQL上建模层次结构的方法.
[SQLAlchemy]是否对使用闭包表创建和遍历对象实例(树结构集合)的分层集合有任何内置支持?
我已经找到了一种与诅咒交互式工作的方法,同时仍然享受着IPython的大部分好处.它的作用有一定的局限性,但并不像我想的那么好.
当然,最初的问题是,我希望能够使用curses(ncurses)模块(例如urwid)控制终端屏幕,同时使用我的交互式Python会话.一种解决方案是编写一个简单的TCP服务器,其中包含一个简单的事件循环,用于评估从套接字读取的每个字符串,并发回代表并返回结果的序列化字符串.如下所述:SO:有没有办法交互式编程Python curses应用程序).
这是一个稍微简单的技巧(假设你安装了IPython).
#!/usr/bin/python
#!/usr/bin/env python
from IPython import embed_kernel
import curses
def interact_with_curses(screen):
'''set global stdscr variable and run embedded IPython kernel
suitable to be called by curses.wrapper()
'''
global stdscr
stdscr = screen
embed_kernel()
if __name__ == '__main__':
curses.wrapper(interact_with_curses)
Run Code Online (Sandbox Code Playgroud)
(稍微勉强让SO的语法突出显示开心).
运行此将导致输出大致如下:
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2869.json
Run Code Online (Sandbox Code Playgroud)
并切换到另一个窗口或屏幕会话,您可以运行:
ipython console --existing kernel-2869.json
Run Code Online (Sandbox Code Playgroud)
连接到该流程并使用它.
这很好.然后你可以调用类似的东西stdscr.refresh()
.使用你的curses/window和pad对象,调用dir()
它们来探索它们的功能,并且通常使用代码,就像你在正常的IPython会话中一样,恰好正在更新不同终端的屏幕并从中读取(通过curses输入函数).
这种方法的问题和问题:
curses.wrapper()
终端和各种尝试重置叫.endwin()
,.resetty()
(已经执行了之后.savetty() …
我正在尝试学习如何编写像Reddit.com这样的网站算法,其中有数千个帖子需要排名.他们的排名算法就像这样(你不必阅读它,它更像是我的一般性问题):http://amix.dk/blog/post/19588
现在我有一个存储在数据库中的帖子,我记录他们的日期,他们每个都有一个upvotes和downvotes字段,所以我存储他们的记录.我想知道你如何存储他们的排名?当特定帖子具有排名值,但它们随时间变化时,您如何存储其排名?
如果它们没有存储,那么每次用户加载页面时,您是否对每个帖子进行排名?
你什么时候存储帖子?你是否运行一个cron作业来每隔x分钟自动为每个帖子提供一个新值?你存储它们的价值吗?这是暂时的.也许,直到那篇文章达到最低分并被遗忘?
这是一个学术而非实际的问题.在旅行推销员问题中,或任何其他涉及寻找最小优化的问题......如果使用地图/减少方法,似乎有一些价值可以将当前最小结果广播给所有人计算节点以某种方式允许它们放弃超过该计算的计算.
换句话说,如果我们将问题映射出来,我们希望每个节点知道何时在完成之前放弃给定的部分结果,但是当它已经超过其他解决方案时.
如果减速器具有向映射器提供反馈的方法,那么立即想到的一种方法是.考虑一下我们是否有100个节点,映射器为它们提供了数百万条路径.如果reducer将最佳结果提供给mapper,那么该值可以作为参数与每个新路径(问题子集)一起包含.在这种方法中,粒度相当粗糙...... 100个节点将在问题的分区上逐渐磨损完成,并且只有来自映射器的下一个请求才能获得新的最小值.(对于少量节点和大量问题分区/子集来说,这种粒度是无关紧要的;也可能是人们可以将启发式方法应用于可能的路由或问题子集被馈送到节点的序列中获得朝向最优的快速收敛,从而最小化节点执行的"浪费"计算量.
想到的另一种方法是节点主动订阅某种频道,或多播甚至广播,从中可以从计算循环中收集新的最小值.在这种情况下,当被通知更好的解决方案时(他们的同行之一),他们可以立即放弃糟糕的计算.
所以,我的问题是:
python ×4
algorithm ×1
ca ×1
cas ×1
correctness ×1
fifo ×1
file-io ×1
ipython ×1
listener ×1
lua ×1
mapreduce ×1
mysql ×1
named-pipes ×1
ncurses ×1
nonblocking ×1
openssl ×1
optimization ×1
php ×1
posix ×1
python-ldap ×1
redis ×1
sql ×1
sqlalchemy ×1
sqlite ×1
styles ×1
triggers ×1