有没有办法让Python静态分析器(例如在PyCharm,其他IDE中)接受argparse.Namespace
对象上的Typehints ?例:
parser = argparse.ArgumentParser()
parser.add_argument('--somearg')
parsed = parser.parse_args(['--somearg','someval']) # type: argparse.Namespace
the_arg = parsed.somearg # <- Pycharm complains that parsed object has no attribute 'somearg'
Run Code Online (Sandbox Code Playgroud)
如果我删除内联注释中的类型声明,PyCharm不会抱怨,但它也不会选择无效的属性.例如:
parser = argparse.ArgumentParser()
parser.add_argument('--somearg')
parsed = parser.parse_args(['--somearg','someval']) # no typehint
the_arg = parsed.somaerg # <- typo in attribute, but no complaint in PyCharm. Raises AttributeError when executed.
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
受奥斯汀在下面的回答的启发,我能找到的最简单的解决方案是namedtuples
:
from collections import namedtuple
ArgNamespace = namedtuple('ArgNamespace', ['some_arg', 'another_arg'])
parser = argparse.ArgumentParser()
parser.add_argument('--some-arg')
parser.add_argument('--another-arg')
parsed …
Run Code Online (Sandbox Code Playgroud) 在为Enum
成员试验不同的值类型时,我发现当值是可变的时会有一些奇怪的行为.
如果我将一个值定义Enum
为不同的列表,那么成员的行为仍然类似于Enum
值是典型的不可变类型,如str
或int
,即使我可以更改成员的值,以便两个Enum
成员的值相同:
>>> class Color(enum.Enum):
black = [1,2]
blue = [1,2,3]
>>> Color.blue is Color.black
False
>>> Color.black == Color.blue
False
>>> Color.black.value.append(3)
>>> Color.black
<Color.black: [1, 2, 3]>
>>> Color.blue
<Color.blue: [1, 2, 3]>
>>> Color.blue == Color.black
False
>>> Color.black.value == Color.blue.value
True
Run Code Online (Sandbox Code Playgroud)
但是,如果我将值定义为相同的列表,则每个成员的值似乎是同一个对象,因此一个成员的值的任何突变都会影响所有成员:
>>> class Color(enum.Enum):
black = [1,2,3]
blue = [1,2,3]
>>> Color.blue is Color.black
True
>>> Color.black == Color.blue
True
>>> …
Run Code Online (Sandbox Code Playgroud) 我有一个测试框架,需要使用以下类模式定义测试用例:
class TestBase:
def __init__(self, params):
self.name = str(self.__class__)
print('initializing test: {} with params: {}'.format(self.name, params))
class TestCase1(TestBase):
def run(self):
print('running test: ' + self.name)
Run Code Online (Sandbox Code Playgroud)
当我创建并运行测试时,我得到以下内容:
>>> test1 = TestCase1('test 1 params')
initializing test: <class '__main__.TestCase1'> with params: test 1 params
>>> test1.run()
running test: <class '__main__.TestCase1'>
Run Code Online (Sandbox Code Playgroud)
测试框架搜索并加载TestCase
它可以找到的所有类,实例化每个类,然后run
为每个测试调用该方法.
load_test(TestCase1(test_params1))
load_test(TestCase2(test_params2))
...
load_test(TestCaseN(test_params3))
...
for test in loaded_tests:
test.run()
Run Code Online (Sandbox Code Playgroud)
但是,我现在有一些测试用例,在__init__
调用方法之前我不希望调用该run
方法,但是我几乎无法控制框架结构或方法.如何在__init__
不重新定义__init__
或run
方法的情况下延迟呼叫?
推测这起源于XY问题是正确的.一段时间,当我维护测试框架时,一位同事问我这个问题.我进一步询问了他真正想要实现的目标,我们想出了一个更简单的解决方法,不涉及更改框架或引入元类等. …
在Python 2中,为什么旧样式类的实例仍然是实例,object
即使它们没有显式继承object
?
class OldClass:
pass
>>> isinstance(OldClass(), object)
True
Run Code Online (Sandbox Code Playgroud)
在测试之前,我会得出结论,isinstance(x, object) == True
这意味着它x
是一个子类object
的实例,因此是新样式类的一个实例,但似乎Python 2中的所有对象都是实例object
(是的,我知道声音有多明显) ).
进一步挖掘,我发现了一些看似奇怪的行为:
>>> issubclass(OldClass, object)
False
Run Code Online (Sandbox Code Playgroud)
我的印象isinstance(x, SomeClass)
实际上相当于issubclass(x.__class__, SomeClass)
,但显然我错过了一些东西.
在阅读了 Rust 书中关于智能指针和内部可变性的部分后,作为个人练习,我尝试编写一个函数来遍历智能指针的链表并返回列表中的“最后一个”元素:
#[derive(Debug, PartialEq)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn get_last(list: &List) -> &List {
match list {
Nil | Cons(_, Nil) => list,
Cons(_, next_list) => get_last(next_list),
}
}
Run Code Online (Sandbox Code Playgroud)
此代码导致以下错误:
| Nil | Cons(_, Nil) => list,
| ^^^ expected struct `std::rc::Rc`, found enum `List
Run Code Online (Sandbox Code Playgroud)
我能够通过使用“匹配保护”并明确取消对Cons(_, x)
模式的引用来使其工作:
fn get_last(list: &List) -> &List {
match list {
Nil => list,
Cons(_, next_list) if **next_list == Nil => list,
Cons(_, next_list) …
Run Code Online (Sandbox Code Playgroud) 这是为什么Python枚举中的可变值是同一对象的后续文章?。
如果an的值Enum
是可变的(例如list
s等),则可以随时更改这些值。我认为如果Enum
按值检索成员会带来一些问题,尤其是如果某人无意中更改了Enum
他查找的an的值:
>>> from enum import Enum
>>> class Color(Enum):
black = [1,2]
blue = [1,2,3]
>>> val_1 = [1,2]
>>> val_2 = [1,2,3]
>>> Color(val_1)
<Color.black: [1, 2]>
>>> Color(val_2)
<Color.blue: [1, 2, 3]>
>>> my_color = Color(val_1)
>>> my_color.value.append(3)
>>> Color(val_2)
<Color.black: [1, 2, 3]>
>>> Color(val_1)
Traceback (most recent call last):
...
ValueError: [1, 2] is not a valid Color
Run Code Online (Sandbox Code Playgroud)
我认为给定普通的Python习惯用法是可以的,这意味着用户可以使用可变变量作为其 …
我从REST API获得了一个字符串列表.我从文档中知道索引0和2处的项是整数,而1和3处的项是浮点数.
要使用我需要将其转换为正确类型的数据进行任何类型的计算.虽然每次使用它时都可以转换值,但我宁愿在开始计算之前将列表转换为正确的类型以保持方程更清晰.下面的代码工作,但非常难看:
rest_response = ['23', '1.45', '1', '1.54']
first_int = int(rest_response[0])
first_float = float(rest_response[1])
second_int = int(rest_response[2])
second_float = float(rest_response[3])
Run Code Online (Sandbox Code Playgroud)
由于我在这个特定的例子中使用整数和浮点数,一种可能的解决方案是将每个项目转换为浮点数.float_response = map(float, rest_response)
.然后我可以简单地解压缩列表以在方程中相应地命名值.
first_int, first_float, second_int, second_float = float_response
Run Code Online (Sandbox Code Playgroud)
这是我目前的解决方案(但有更好的名字),但在找出一个我感到好奇,如果有任何好的pythonic解决这种问题?
我有一个使用 https 设置的个人 Python 存储库,我可以使用以下命令上传到它:
twine upload <dist> -r <my_server> --cert <path/to/certfile>
Run Code Online (Sandbox Code Playgroud)
但是,我希望能够上传而无需显式指定 CA 证书位置。我相信我已将 CA 证书安装在系统的正确位置(使用 如何在 centos7 中添加证书颁发机构?作为指导,并使用 wget 进行验证),但我仍然需要调用原始路径。
如何让 twine 默认使用我的备用 CA 证书?
python ×7
python-3.x ×4
enums ×2
argparse ×1
centos7 ×1
class ×1
coercion ×1
dereference ×1
dictionary ×1
hashable ×1
identity ×1
isinstance ×1
pycharm ×1
pypiserver ×1
python-2.x ×1
rust ×1
twine ×1
type-hinting ×1