为什么C++允许编译以下代码?
std::unordered_map<std::string, int> m;
// ...
for (const std::pair<std::string, int>& p: m)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
根据Scott Meyers的Effective Modern C++(p.40-41):
[...] a的关键部分
std::unordered_map是const,所以std::pair哈希表中的类型(它是什么std::unordered_map)不是std::pair<std::string, int>,它是std::pair <const std::string, int>.但这不是p上面循环中为变量声明的类型.因此,编译器将努力找到一种方法将std::pair<const std::string, int>对象(即哈希表中的内容)转换为std::pair<std::string, int>对象(声明的类型p).它们将p通过复制每个对象来创建一个想要绑定的类型的临时对象m,然后将引用p绑定到该临时对象.在每次循环迭代结束时,临时对象将被销毁.如果你编写了这个循环,你可能会对这种行为感到惊讶,因为你几乎肯定打算简单地将引用绑定p到每个元素中m.
允许这种隐式转换有什么好处?是否有一些常见的用例,开发人员期望/更喜欢这种隐式转换(而不是获得编译器错误)?
我需要找到,处理和删除(逐个)任何匹配相当长的正则表达式的子串:
# p is a compiled regex
# s is a string
while 1:
m = p.match(s)
if m is None:
break
process(m.group(0)) #do something with the matched pattern
s = re.sub(m.group(0), '', s) #remove it from string s
Run Code Online (Sandbox Code Playgroud)
上面的代码有两个原因:
如果m.group(0)恰好包含任何正则表达式特殊字符(如*,+等),则不起作用.
感觉就像我正在重复工作:首先我在字符串中搜索正则表达式,然后我必须再次寻找它以删除它.
这样做的好方法是什么?
from multiprocessing import Process
# c is a container
p = Process(target = f, args = (c,))
p.start()
Run Code Online (Sandbox Code Playgroud)
我假设将深层副本c传递给函数,f因为浅层副本在新进程的情况下没有任何意义(新进程无法访问调用进程中的数据).
但这个深层副本是如何定义的?这里有一整集的笔记中copy.deepcopy()的文档,做所有这些说明适用于这里?该multiprocessing文件说什么?
命名容器时,有什么更好的编码风格:
source = {}
#...
source[record] = some_file
Run Code Online (Sandbox Code Playgroud)
要么
sources = {}
#...
sources[record] = some_file
Run Code Online (Sandbox Code Playgroud)
复数在创作时更自然; 任务中的单数.
这不是一个无所事事的问题; 当我不确定变量是容器还是单个值时,我确实发现自己在旧代码中感到困惑.
UPDATE
看来人们普遍认为,当字典用作映射时,最好使用更详细的名称(例如recordToSourceFilename); 如果我绝对想要使用短名称,那么将其复数(例如sources).
Python 2支持无缓冲的文本I/O.
同样的方法在python 3中不起作用.为什么禁用了无缓冲的文本I/O?
> import sys
> sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
builtins.ValueError: can't have unbuffered text I/O
Run Code Online (Sandbox Code Playgroud)
二进制文件仍然正常工作:
> sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0) # works fine
Run Code Online (Sandbox Code Playgroud) 是否有任何障碍阻止weakref做一切__del__但有更强保证的事情(例如,finalize保证在解释器退出之前进行呼叫,并且呼叫的顺序是明确定义的等等)?
看来,在遥远的过去,人们认为这weakref将最终导致去除__del__从语言.
什么阻止了这种情况发生?
似乎很少有用例__del__,而且我所知道的所有用例似乎至少与weakref回调或(或通常更好)一起使用回调或weakref.finalize.
更新:
随着PEP 442显着改善了@gz和@ user2357112所提__del__及的行为和问题weakref,我想知道这种语言是否通常朝着__del__更可靠的方向发展,或者转向使用weakref而不是__del__两者兼有.
python garbage-collection destructor weak-references python-3.x
我正在尝试创建一个传递参数x并返回一个新类的函数C.C应该是固定基类的子类A,只有一个加法:添加某个类属性并设置为相等x.
换一种说法:
class C(A):
C.p = x # x is the parameter passed to the factory function
Run Code Online (Sandbox Code Playgroud)
这很容易吗?我应该注意哪些问题?
class ABC是一个"抽象基类".class X是它的子类.
有些工作需要在任何子类中完成ABC,这很容易忘记或做错.我想ABC.__init__()通过以下两种方式来帮助解决这些错误:
(1)开始这项工作,或(2)验证它
这会影响super().__init__()是在开始时还是在结束时调用X.__init__().
以下是用于说明目的的简化示例:
假设每个子类ABC必须具有一个属性registry,并且它必须是一个列表.ABC.__init__()可以(1)初始化registry或(2)检查它是否正确创建.以下是每种方法的示例代码.
方法1:在ABC中初始化
class ABC:
def __init__(self):
self.registry = []
class X:
def __init__(self):
super().__init__()
# populate self.registry here
...
Run Code Online (Sandbox Code Playgroud)
方法2:在ABC中验证
class ABC:
class InitializationFailure(Exception):
pass
def __init__(self):
try:
if not isinstance(self.registry, list):
raise ABC.InitializationError()
except AttributeError:
raise ABC.InitializationError()
class X:
def __init__(self):
self.registry = []
# populate self.registry here
...
super().__init__()
Run Code Online (Sandbox Code Playgroud)
哪个更好的设计?
是否有两个不同的命令来生成新变量?
是否有一种简单的方法可以记住何时使用gen以及何时使用egen?
它是众所周知的(和理解)分配到切片时,大熊猫的行为本质上是不可预测的.但我常常被警告SettingWithCopy警告.
为什么警告不是在以下两个代码片段中生成的,哪些技术可以减少无意中编写此类代码的可能性?
# pandas 0.18.1, python 3.5.1
import pandas as pd
data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
new_data = data[['a', 'b']]
data = data['a']
new_data.loc[0, 'a'] = 100 # no warning, doesn't propagate to data
data[0] == 1
True
data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
new_data = data['a']
data = data['a']
new_data.loc[0] = 100 # no warning, propagates to data
data[0] == 100
True
Run Code Online (Sandbox Code Playgroud)
我认为解释是,当父数据帧仍可从当前上下文访问时,pandas仅生成警告.(这将是检测算法的一个弱点,正如我之前的例子所示.)
在下一个片段中,AFAIK原始的双列DataFrame不再可访问,但pandas警告机制设法触发(幸运的是): …
python ×8
python-3.x ×3
c++ ×1
c++11 ×1
class-design ×1
coding-style ×1
const ×1
containers ×1
deep-copy ×1
destructor ×1
identifier ×1
io ×1
oop ×1
pandas ×1
regex ×1
stata ×1
templates ×1