![](/img/trans.png)
[英]Python development on Mac OS X: pure Mac OS or linux in virtualbox
[英]On OS X, is it possible to get the user library directory from pure Python?
我正在编写一个纯Python库,出于各种原因,我非常想避免要求用户安装任何二进制扩展名。 但是,在OS X上运行时,我也想找到用户库目录( ~/Library
),以便在其中存储一些配置数据,我的理解是,对于“非常有效且含糊但重要的原因”,正确的做法是这不仅仅是通过在我的代码中编写~/Library
,而是通过询问OS X目录中包含一些代码的地方,例如
[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask,
YES)
objectAtIndex:0];
当然,此代码是Objective-C,而不是Python,因此我不能直接使用它。 如果它是纯C语言,我只会使用ctypes
从Python调用它,但事实并非如此。 有什么方法可以从Python进行此调用,而无需在Objective-C中编写扩展模块或要求用户安装某些扩展模块(如PyObjC
? 或者,如果我像其他所有人一样放弃并硬编码~/Library
,那么会发生什么可怕的事情吗?
好吧, 它是底层的普通C语言,因此您可以使用ctypes
模块获得相同的结果:
from ctypes import *
NSLibraryDirectory = 5
NSUserDomainMask = 1
def NSSearchPathForDirectoriesInDomains(directory, domainMask, expand = True):
# If library path looks like framework, OS X will search $DYLD_FRAMEWORK_PATHs automatically
# There's no need to specify full path (/System/Library/Frameworks/...)
Foundation = cdll.LoadLibrary("Foundation.framework/Foundation")
CoreFoundation = cdll.LoadLibrary("CoreFoundation.framework/CoreFoundation");
_NSSearchPathForDirectoriesInDomains = Foundation.NSSearchPathForDirectoriesInDomains
_NSSearchPathForDirectoriesInDomains.argtypes = [ c_uint, c_uint, c_bool ]
_NSSearchPathForDirectoriesInDomains.restype = c_void_p
_CFRelease = CoreFoundation.CFRelease
_CFRelease.argtypes = [ c_void_p ]
_CFArrayGetCount = CoreFoundation.CFArrayGetCount
_CFArrayGetCount.argtypes = [ c_void_p ]
_CFArrayGetCount.restype = c_uint
_CFArrayGetValueAtIndex = CoreFoundation.CFArrayGetValueAtIndex
_CFArrayGetValueAtIndex.argtypes = [ c_void_p, c_uint ]
_CFArrayGetValueAtIndex.restype = c_void_p
_CFStringGetCString = CoreFoundation.CFStringGetCString
_CFStringGetCString.argtypes = [ c_void_p, c_char_p, c_uint, c_uint ]
_CFStringGetCString.restype = c_bool
kCFStringEncodingUTF8 = 0x08000100
# MAX_PATH on POSIX is usually 4096, so it should be enough
# It might be determined dynamically, but don't bother for now
MAX_PATH = 4096
result = []
paths = _NSSearchPathForDirectoriesInDomains(directory, domainMask, expand)
# CFArrayGetCount will crash if argument is NULL
# Even though NSSearchPathForDirectoriesInDomains never returns null, we'd better check it
if paths:
for i in range(0, _CFArrayGetCount(paths)):
path = _CFArrayGetValueAtIndex(paths, i)
buff = create_string_buffer(MAX_PATH)
if _CFStringGetCString(path, buff, sizeof(buff), kCFStringEncodingUTF8):
result.append(buff.raw.decode('utf-8').rstrip('\0'))
del buff
_CFRelease(paths)
return result
print NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask)
但是如果只使用~/Library
,宇宙可能不会崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.