我有一个函数返回一个class instance
或None
依赖于某些逻辑。\n在代码的某些地方我知道这个函数肯定不会返回None
,\n但 mypy 抱怨。
我做了一个最小的例子来重现上述情况。
\n\n我想避免标记a_string
为,我\n知道我也可以使用或a_string: Optional[str] = ""
克服问题,但不知何故我\n觉得可能有更好的方法。cast
type ignore
有什么建议如何处理这种情况?
\n\n对于这个例子,我使用mypy 0.641
和python 3.7
"""\nFunction returns either an object or none\n\n"""\n\nfrom typing import Optional, cast\n\nRET_NONE = False\n\n\ndef minimal_example() -> Optional[str]:\n if RET_NONE:\n return None\n else:\n return "my string"\n\n\na_string = ""\nmaybe_string = minimal_example()\na_string = maybe_string\n\n# mypy doesn\'t complain if I do the following\na_string = cast(str, maybe_string)\na_string = maybe_string # type: ignore\n …
Run Code Online (Sandbox Code Playgroud) 如何在不重新定义的情况下提取 python 枚举子集?
from enum import unique, Enum
@unique
class MyEnum(Enum):
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
Run Code Online (Sandbox Code Playgroud)
我想获得相当于MyDesiredSubset
而不必再次定义它。
@unique
class MyDesiredSubset(Enum):
THREE = 3
FOUR = 4
Run Code Online (Sandbox Code Playgroud)
到目前为止,我尝试过这样的事情,但MyTrySubset
被破坏了,代码也很丑陋。
@unique
class MyTrySubset(Enum):
pass
for item in MyEnum:
setattr(MyTrySubset, item.name, item.value)
Run Code Online (Sandbox Code Playgroud)
任何建议如何在MyDesiredSubset
不重新定义的情况下获得?
有没有办法让 mypy 对这段代码感到满意而无需更改class Config
,目前我无法更改该类(对 cli 应用程序使用 typer)。我知道我可以使用# type: ignore
,但是还有其他解决方案吗?
"""
mypy --version
mypy 0.812
"""
from enum import Enum
from pathlib import Path
from typing_extensions import Literal
class Config(str, Enum):
Debug = 'Debug'
Release = 'Release'
BuildMode = Literal["ASAN", "UBSAN", "Coverage", "Release", "Debug"]
def run_c_tests(results_dir: Path, mode: BuildMode):
...
configuration = Config.Debug
# mypy error: Argument 2 to "run_c_tests" has incompatible type "str"; expected "Union[Literal['ASAN'], Literal['UBSAN'], Literal['Coverage'], Literal['Release'], Literal['Debug']]"
run_c_tests(Path('apath'), configuration.value)
Run Code Online (Sandbox Code Playgroud)
Mypy v0.782 不会抱怨上面的代码,但 0.812 会抱怨。
以下代码产生一个警告,但我预计会产生两个警告;我每次写一个CString::new("A CString").unwrap().as_ptr()
:
use std::ffi::CString;
use std::os::raw::c_char;
extern "C" {
fn puts(s: *const c_char);
}
macro_rules! mymacro {
() => {
puts(CString::new("A CString").unwrap().as_ptr());
};
}
fn main() {
unsafe {
puts(CString::new("A CString").unwrap().as_ptr());
mymacro!();
}
}
Run Code Online (Sandbox Code Playgroud)
warning: getting the inner pointer of a temporary `CString`
--> src/main.rs:16:49
|
16 | puts(CString::new("A CString").unwrap().as_ptr());
| ---------------------------------- ^^^^^^ this pointer will be invalid
| |
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend …
Run Code Online (Sandbox Code Playgroud) 试图解决如何从不同线程将内容插入到 hasmap 的问题,但仍然无法得到它。
为什么以下程序在每次执行时都会缺少一些键?我目前的理解是.write
等待获取锁并.join
等待所有线程完成?
因此,我希望最终所有线程都将它们的值插入到哈希图中,但显然我仍然缺少一些东西。
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::RwLock;
use std::thread;
use std::vec;
pub fn main() {
let mut contacts: HashMap<String, String> = HashMap::new();
contacts.insert("main-thread".to_owned(), "hello world".to_owned());
let contacts = Arc::new(RwLock::new(contacts));
let mut children = vec![];
for _ in 0..10 {
let lock_contacts = Arc::clone(&contacts);
children.push(thread::spawn(move || {
let num = thread::current().id();
let num = format!("{num:?}");
if let Ok(mut contacts) = lock_contacts.write() {
contacts.insert(num.clone(), "hey".to_owned());
}
}));
}
let _ = children.into_iter().map(|c| c.join()); …
Run Code Online (Sandbox Code Playgroud) 是否有更好的方法使用std::path::Path使祖先在文件夹结构层次结构中上升几级?
目前,如果想要获得 5 级以上的祖先,我会执行以下操作(见下文),但我觉得一定有更好的方法。
我知道方法祖先,但我不知道如何使用它来改进这个片段。
use std::path::PathBuf;
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let ancestor_dir = out_dir
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap();
Run Code Online (Sandbox Code Playgroud)
这个可以写成更易读的方式吗?