注意:对象生命周期RAII不使用/与块范围RAII
似乎可以使用额外的gc类别,短期对象(经常检查gc类别),长期存在的对象(不常检查gc类别)和资源对象(非常频繁地检查gc类别).或者可能使用额外的引用计数资源对象的gc.
似乎使用/ with style可以通过促进I/O的更多功能风格(原谅我,如果我错了,这不是功能风格)来阻止大量的I/O扩散到地方vs基于对象的RAII的灵活性(因为它更容易).但是一些问题可能需要很难跟踪资源的生命周期.
有没有理由除了避免gc的复杂性和速度,还没有在主流语言上做到这一点?(我知道有些语言在其主要实现中使用引用计数作为gc的一部分,因此,RAII可能在那里工作,但我认为他们的规范没有为某些类型的对象/或所有对象指定引用计数,并且人们使用的其他实现没有引用计数,限制了对象生存期RAII在这些语言中的使用.
PS:他们在perl中有c ++类型的RAII吗?
garbage-collection raii using-statement with-statement object-lifetime
是否有重构工具来删除"with"块?例如转换
with Form1 do
begin
Height := Blah;
Blubb := Name;
end;
Run Code Online (Sandbox Code Playgroud)
至
Form1.Height := Blah;
Blubb := Form1.Name;
Run Code Online (Sandbox Code Playgroud)
其中Form1是VCL TForm.最好它应该与Delphi 2007一起使用.
我已经读过使用以下格式打开文件时
with open(filename) as f:
#My Code
f.close()
Run Code Online (Sandbox Code Playgroud)
不需要显式关闭文件.有人可以解释为什么会这样吗?此外,如果有人明确关闭文件,它会有任何不良影响吗?
如果进程无法解锁,可能会发生可怕的事情multiprocessing.为了最大限度地减少发生这种情况的可能性,我想获得一个with块中的锁.有没有内置的方法可以做到这一点,还是我需要自己动手?
我已经读过,这样打开的文件会在离开with块时自动关闭:
with open("x.txt") as f:
data = f.read()
do something with data
Run Code Online (Sandbox Code Playgroud)
但是当从网上开放时,我需要这个:
from contextlib import closing
from urllib.request import urlopen
with closing(urlopen('http://www.python.org')) as page:
for line in page:
print(line)
Run Code Online (Sandbox Code Playgroud)
为什么和有什么区别?(我使用的是Python3)
以下是pymysql中的示例:
conn = pymysql.connect(...)
with conn.cursor() as cursor:
cursor.execute(...)
...
conn.close()
Run Code Online (Sandbox Code Playgroud)
我可以使用以下内容,还是会留下一个挥之不去的连接?(它成功执行)
import pymysql
with pymysql.connect(...) as cursor:
cursor.execute('show tables')
Run Code Online (Sandbox Code Playgroud)
(python 3,最新的pymysql)
试图正确删除Python对象.我正在创建一个对象,然后假设用'with'语句删除它.但是当'with'语句关闭后我打印出来时......对象仍然存在:
class Things(object):
def __init__(self, clothes, food, money):
self.clothes = clothes
self.food = food
self.money = money
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('object deleted')
with Things('socks','food',12) as stuff:
greg = stuff.clothes
print(greg)
print(stuff.clothes)
Run Code Online (Sandbox Code Playgroud)
回报:
socks
object deleted
socks
Run Code Online (Sandbox Code Playgroud) with(new Proxy({}, {
has() { return true },
get(obj, key, proxy) { return console.log(String(key)) } })
) {
a--
}Run Code Online (Sandbox Code Playgroud)
Chrome中的输出:
Symbol(Symbol.unscopables)
a
Symbol(Symbol.unscopables)
Run Code Online (Sandbox Code Playgroud)
Firefox中的输出:
Symbol(Symbol.unscopables)
Symbol(Symbol.unscopables)
a
Run Code Online (Sandbox Code Playgroud)
据我所知,一个人获得与阅读价值相关 - 另一个 - 分配.
不,这不对.a--应该写入a读取的同一个地方是合乎逻辑的.
但是Symbol.unscopables两次获得价值提示我们,可以传递一个对象进行阅读,另一个对象进行写作.
它真的意味着像那样工作吗?规范说什么?
实际上,它几乎可以在Chrome和FF中运行 - 它可以从一个对象读取并写入另一个对象,但它会导致不同的结果:
更新:Safari 10只读取一次.
var a, b, flag = true
with (a = { x: 7 })
with (b = { x: 4, get [Symbol.unscopables]() { return { x: flag=!flag } } })
x++
// Chrome FF …Run Code Online (Sandbox Code Playgroud)我经常需要用别的东西临时切换一个变量的值,做一些依赖于这个变量的计算,然后将变量恢复到它的原始值。例如:
var = 0
# Assign temporary value and do computation
var_ori = var
var = 1
do_something_with_var() # Function that reads the module level var variable
# Reassign original value
var = var_ori
Run Code Online (Sandbox Code Playgroud)
这似乎是使用上下文管理器(with语句)的明显机会。Python 标准库是否包含任何这样的上下文管理器?
我知道这种事情通常由其他更好的方法处理,而不是临时更改变量。然而,我并不是要求明显的解决方法。
在我的实际工作案例中,我无法更改该do_something_with_var功能。实际上,这甚至不是一个函数,而是作为元编程的一部分在全局命名空间上下文中求值的一串代码。我给出的例子是我能想到的最简单的例子,它使我的问题与临时变量有关。我没有要求获得我的示例代码的解决方法(正确版本),而是要求获得我书面问题的答案。
F#有一个方便的功能"with",例如:
type Product = { Name:string; Price:int };;
let p = { Name="Test"; Price=42; };;
let p2 = { p with Name="Test2" };;
Run Code Online (Sandbox Code Playgroud)
F#创建关键字"with"作为记录类型默认是不可变的.
现在,是否可以在C#中定义类似的扩展?看起来有点棘手,就像在C#中我不确定如何转换字符串
Name="Test2"
Run Code Online (Sandbox Code Playgroud)
代表或表达?
with-statement ×10
python ×6
c# ×1
delphi ×1
delphi-2007 ×1
ecmascript-6 ×1
f# ×1
file ×1
immutability ×1
javascript ×1
pymysql ×1
python-3.x ×1
raii ×1
refactoring ×1
urlopen ×1