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)
代表或表达?
我正在学习Python,我正在尝试这个with **** as ****:陈述.我认为它的工作方式与C#很相似using(****) {,但我担心我会跟踪过时的例子.
这是我的代码:
# -*- coding: iso-8859-1 -*-
import pprint
pow = 1, 2, 3
with pprint.pprint as pprint:
pprint(pow)
Run Code Online (Sandbox Code Playgroud)
我假设这里发生的事情是pprint在我的小闭包中是pprint.pprint函数的别名.我遇到了一个奇怪的错误:
Traceback (most recent call last):
File "test.py", line 7, in <module>
with pprint.pprint as pprint:
AttributeError: __exit__
Run Code Online (Sandbox Code Playgroud)
所以现在我想我正在使用旧版Python的语法,就像我之前做的那样(print "Hello")
为什么我的代码不按预期工作?
标准库open函数既可以作为函数使用:
f = open('file.txt')
print(type(f))
<type 'file'>
Run Code Online (Sandbox Code Playgroud)
或作为上下文管理者:
with open('file.txt') as f:
print(type(f))
<type 'file'>
Run Code Online (Sandbox Code Playgroud)
我试图模仿这种行为contextlib.closing,File我的自定义文件I/O类在哪里:
def myopen(filename):
f = File(filename)
f.open()
return closing(f)
Run Code Online (Sandbox Code Playgroud)
这可以像上下文管理器一样工作:
with myopen('file.txt') as f:
print(type(f))
<class '__main__.File'>
Run Code Online (Sandbox Code Playgroud)
但是当然如果我直接打电话,我会收回closing对象而不是我的对象:
f = myopen(filename)
print(type(f))
<class 'contextlib.closing'>
Run Code Online (Sandbox Code Playgroud)
那么,我myopen该如何实现它以便它既作为上下文管理器又直接调用时返回我的File对象?
github上的完整工作示例:https: //gist.github.com/1352573
我有一些解析csv文件的python代码.现在我们的供应商决定将数据文件更改为gzip csv文件.我想知道我必须做出的最小/最干净的代码更改是什么.当前功能:
def load_data(fname, cols=()):
... ...
with open(fname) as f:
reader = csv.DictReader(f)
... ...
Run Code Online (Sandbox Code Playgroud)
我不想将代码复制到load_data2(),并将with语句更改为,认为它完美无缺.
with gzip.open(fname) as f:
Run Code Online (Sandbox Code Playgroud)
如何分析with语句?
def load_data(fname, cols=()):
... ...
if fname.endswith('.csv.gz'):
with gzip.open(fname) as f:
else:
with open(fname) as f:
reader = csv.DictReader(f)
... ... # code to parse
Run Code Online (Sandbox Code Playgroud) Python 3.4提供了这个简洁的工具来暂时重定向stdout:
# From https://docs.python.org/3.4/library/contextlib.html#contextlib.redirect_stdout
with redirect_stdout(sys.stderr):
help(pow)
Run Code Online (Sandbox Code Playgroud)
代码并不是非常复杂,但我不想一遍又一遍地写它,特别是因为有些想法已经进入它以使它重新进入:
class redirect_stdout:
def __init__(self, new_target):
self._new_target = new_target
# We use a list of old targets to make this CM re-entrant
self._old_targets = []
def __enter__(self):
self._old_targets.append(sys.stdout)
sys.stdout = self._new_target
return self._new_target
def __exit__(self, exctype, excinst, exctb):
sys.stdout = self._old_targets.pop()
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一般方法使用该with语句来临时更改变量的值.从另外两个用例sys是sys.stderr和sys.excepthook.
在一个完美的世界中,这样的东西会起作用:
foo = 10
with 20 as foo:
print(foo) # 20
print (foo) # 10
Run Code Online (Sandbox Code Playgroud)
我怀疑我们能做到这一点,但也许这样的事情是可能的:
foo = 10
with temporary_set('foo', …Run Code Online (Sandbox Code Playgroud) 我有以下两种关系:
Game(id, name, year)
Devs(pid, gid, role)
Run Code Online (Sandbox Code Playgroud)
Game.id是主键,Devs.gid是Game.id的外键.
在我之前发表的一篇文章中,另一位用户非常友好地帮助我创建了一个查询,该查询可以找到大多数开发者制作该游戏的所有游戏.他的回答使用了WITH语句,我对这些并不十分熟悉,因为我只用了几周时间学习SQL.这是工作查询:
WITH GamesDevs (GameName, DevsCount)
AS
(
SELECT Game.name AS GameName, count(DISTINCT Devs.pid) AS DevsCount
FROM Game, Devs
WHERE Devs.gid=Game.id
GROUP BY Devs.gid, Game.name
)
SELECT * FROM GamesDevs WHERE GamesDevs.DevsCount = (SELECT MAX(DevsCount) FROM GamesDevs)
Run Code Online (Sandbox Code Playgroud)
为了更熟悉SQL,我试图使用子查询而不是WITH语句重写此查询.我一直在使用这个Oracle文档来帮助我解决这个问题.我尝试重写这样的查询:
SELECT *
FROM (SELECT Game.name AS GameName, count(DISTINCT Devs.pid) AS DevsCount
FROM Game, Devs
WHERE Devs.gid=Game.id
GROUP BY Devs.gid, Game.name) GamesDevs
WHERE GamesDevs.DevsCount = (SELECT MAX(DevsCount) FROM GamesDevs)
Run Code Online (Sandbox Code Playgroud)
据我所知,这两个查询应该是相同的.但是,当我尝试运行第二个查询时,我收到错误 …
什么是PEP-8-ify的pythonic方式,例如with语句:
with tempfile.NamedTemporaryFile(prefix='malt_input.conll.', dir=self.working_dir, mode='w', delete=False) as input_file, tempfile.NamedTemporaryFile(prefix='malt_output.conll.', dir=self.working_dir, mode='w', delete=False) as output_file:
pass
Run Code Online (Sandbox Code Playgroud)
我可以这样做,但由于临时文件i/o没有with声明,它是否会在with后自动关闭?那是pythonic吗?:
intemp = tempfile.NamedTemporaryFile(prefix='malt_input.conll.', dir=self.working_dir, mode='w', delete=False)
outtemp = tempfile.NamedTemporaryFile(prefix='malt_output.conll.', dir=self.working_dir, mode='w', delete=False)
with intemp as input_file, outtemp as output_file:
pass
Run Code Online (Sandbox Code Playgroud)
或者我可以使用斜杠:
with tempfile.NamedTemporaryFile(prefix='malt_input.conll.',
dir=self.working_dir, mode='w', delete=False) as input_file, \
tempfile.NamedTemporaryFile(prefix='malt_output.conll.',
dir=self.working_dir, mode='w', delete=False) as output_file:
pass
Run Code Online (Sandbox Code Playgroud)
但PEP8是否符合要求?那是pythonic吗?
这两个陈述是否相同?
with A() as a, B() as b:
# do something
with A() as a:
with B() as b:
# do something
Run Code Online (Sandbox Code Playgroud)
我问,因为这两个a和b改变全局变量(tensorflow在这里),并b依赖于所做的更改a.所以我知道第二种形式可以安全使用,但是它相当于将它缩短到第一种形式吗?
比如,我有一个JavaScript库来生成如下所示的DOM片段
<main>
<h1>A heading</h1>
<p>A paragraph</p>
</main>
Run Code Online (Sandbox Code Playgroud)
库,domlib包含任何类型元素的方法,以及生成上述片段的函数可能如下所示:
function(domlib){
return domlib.main(
domlib.h1('A heading'),
domlib.p('A paragraph')
);
}
Run Code Online (Sandbox Code Playgroud)
在这个函数中,我宁愿调用这样的domlib方法:
main(
h1('A heading'),
p('A paragraph')
)
Run Code Online (Sandbox Code Playgroud)
为实现这一目标,我可以将所有方法domlib放在全局范围内,但我宁愿避免污染全局范围.对我而言,这似乎with是一个理想的解决方案:
function(domlib){
with(domlib){
return main(
h1('A heading'),
p('A paragraph')
);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然仍然受支持,但该with语句实际上已弃用,并将在严格模式下抛出错误.
我没有看到很多其他选项,除了将domlib方法分配给本地函数变量,但这很容易导致数十个局部变量的分配,在这种情况下,第一种方法(domlib直接调用方法)将导致更简单的代码.
我的问题是,是否有其他替代方案可以实现我想要的,具有与使用with语句类似的简单性和可读性?
首先,我需要道歉,因为我还不能为我的问题提供明确的MCVE。我的问题是关于我在代码库深处遇到的一个奇怪现象,我想了解这是如何发生的,所以在某种程度上,我首先要问的是如何为这种现象创建MCVE。
as在with根本不使用分配变量的语句中是否使用子句怎么会很重要?
我们正在使用 Airflow(Apache 项目),其中存在一个名为的类DAG。此类应该用作以下with子句的上下文管理器:
with DAG(**some_parameters) as dag:
do_something_with(dag)
Run Code Online (Sandbox Code Playgroud)
这按预期工作。
但是,在某些情况下,我们不会dag在with子句中使用该变量,因此 IDE 会发出警告,接下来将其重命名为_dag(以声明不使用),我尝试as dag完全删除该子句:
with DAG(**some_parameters):
do_something_without_passing_dag()
Run Code Online (Sandbox Code Playgroud)
根据我对 Python 的理解,这应该等同as dag于运行时带有子句的版本:
with DAG(**some_parameters) as dag:
do_something_without_passing_dag()
Run Code Online (Sandbox Code Playgroud)
但是,令人惊讶的是,在 Airflow 项目的背景下,两者之间似乎存在差异。使用该as dag子句,代码按预期工作;如果没有该as dag子句,则会显示错误(请参阅本文末尾)。令人沮丧的是,此错误出现在 Airflow 进程的日志中,并且根本不包含对我的代码的引用。
我需要指出的是,在 Airflow 上下文中,这些with语句位于小模块的顶层,因此该as语句会创建一个模块全局变量(如果存在)。我不知道这是否相关。如果是这样,我不明白为什么。
我的理解,它应该永远不会有任何区别我是否提供了一个as条款或不,如果我完全不使用变量。尽管如此,情况似乎仍然如此。
我已经调查了三个方面:
__enter__()了DAG …with-statement ×10
python ×7
c# ×1
f# ×1
file-io ×1
immutability ×1
javascript ×1
pep8 ×1
python-3.x ×1
scope ×1
sql ×1