Tôi đang viết một lớp
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
1 với phương pháp import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
2 tích hợp:from pyparsing import Word, nums, Optional, Suppress
class PortRange[object]:
def __init__[self, start, end=None]:
self.start = start
self.end = end if end is not None else self.start
@staticmethod
def parse[string]:
port = Word[nums]
assignmentExpr = port.setResultsName['start'] + Optional[Suppress["-"] + port.setResultsName['end']]
assignmentTokens = assignmentExpr.parseString[string]
start = int[assignmentTokens.start]
end = int[assignmentTokens.end]
return PortRange[start=start, end=end]
Đối tượng
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
1 có các thuộc tính import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
4 và import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
5 và nếu import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
5 được đưa ra là import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
7 trong hàm tạo, nó được coi là giống như bắt đầu.import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
1 cũng có một biểu diễn chuỗi: nếu import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
4 và import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
5 bằng nhau, thì đó chỉ là một số, trong khi nếu chúng khác nhau, chúng được phân tách bằng dấu gạch nối [ví dụ: int['']
1]. Tôi đang cố gắng viết một phương thức import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
2 phân tích chính xác cả hai trường hợp bằng cách sử dụng pyparsing. Cuối cùng, tôi đã viết các bài kiểm tra sau:import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
Vấn đề là bài kiểm tra thứ hai thất bại, bởi vì cuối cùng bạn đang cố gắng thực hiện
int['']
dẫn đến
int['']
3. Trong hàm import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
2, tôi muốn import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
5 trở thành import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
7, tương tự như nếu tôi viết một biểu thức chính quy với tên nhóm tượng trưng và sử dụng int['']
7.Làm thế nào tôi có thể đạt được điều này? [Tôi đã thử xác định lại
int['']
8 là int['']
9, nhưng điều này dẫn đến def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth0 do 0 đối số vào
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth1].
Vấn đề mới
Có một câu hỏi về dự án này? Đăng ký một tài khoản GitHub miễn phí để mở một vấn đề và liên hệ với người bảo trì và cộng đồng của nó. Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Bằng cách nhấp vào Đăng ký đăng ký cho GitHub, bạn đồng ý với Điều khoản dịch vụ và tuyên bố quyền riêng tư của chúng tôi. Chúng tôi thỉnh thoảng gửi cho bạn các email liên quan đến tài khoản.
Đã có trên Github? đăng nhập vào tài khoản của bạn
Đóng
Cjerdonek đã mở vấn đề này
Ngày 11 tháng 6 năm 2019· 10 bình luận
Bình luận
Gần đây tôi đã nhận thấy rằng sẽ rất hữu ích khi có một biến thể
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth2 loại bỏ
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth3 [ví dụ: cho mục đích khô]. Điều này sẽ hữu ích trong trường hợp mã trước đó đã loại trừ trường hợp
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
7 và ví dụ: suy luận loại của MyPy không thể phát hiện ra nó. Tôi tin rằng điều này cũng có thể giúp ngăn ngừa lỗi vì mọi người có thể chuyển sai def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth5 vào
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth2 [hoặc mã có thể thay đổi theo thời gian, v.v.].
Điều này có liên quan đến [hoặc trường hợp đặc biệt của] vấn đề #565. Tôi xin lỗi trước nếu tính năng này đã tồn tại hoặc nếu ý tưởng đã bị từ chối.
Tôi không nghĩ nó tồn tại. Hãy để tôi xem nếu tôi hiểu bạn một cách chính xác.
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth
Lỗi trên dòng cuối cùng là dương tính giả vì
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth7 kiểm tra cho
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
7.Vì vậy, bạn sẽ muốn viết một cái gì đó như
arg = cast_away_optional[arg] reveal_type[arg] # Should print C, not Optional[C] return arg.meth[] # Should not be an error
Tôi có đúng không?
Nó không hoàn toàn giống nhau, nhưng MyPy đã hỗ trợ làm điều này với các xác nhận:
$ mypy -c '''
from typing import Optional
def f[x: Optional[int]] -> None:
reveal_type[x]
assert x is not None
reveal_type[x]
'''
:4: error: Revealed type is 'Union[builtins.int, None]'
:6: error: Revealed type is 'builtins.int'
Tất nhiên, không giống như hoạt động diễn viên được đề xuất, điều này cũng thực hiện kiểm tra thời gian chạy.
Có khả năng chi phí thời gian chạy của một so sánh
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth9 ít hơn so với một cuộc gọi chức năng không op duy nhất. Vì vậy, có vẻ như Assert là giải pháp tốt hơn. @cjerdonek bạn có đồng ý không?
Sự khẳng định là điều tốt để biết [tôi không biết về điều đó khi tôi nộp vấn đề này] và tôi đồng ý là tốt cho những trường hợp đó. Tuy nhiên, có ít nhất một trường hợp có vẻ như nó có thể không tốt như vậy [và là một trong những lý do khiến tôi phải nộp đơn này]. Lấy đoạn trích này từ cơ sở mã của PIP:
for line in data.split[b'\n'][:2]: if line[0:1] == b'#' and ENCODING_RE.search[line]: encoding = ENCODING_RE.search[line].groups[][0].decode['ascii'] return data.decode[encoding]
.
Ở đây, vấn đề là sau khi kiểm tra nếu chúng ta biết rằng giá trị trả về của cuộc gọi phương thức [
arg = cast_away_optional[arg] reveal_type[arg] # Should print C, not Optional[C] return arg.meth[] # Should not be an error0] sẽ không phải là
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
7. Một chức năng diễn viên như tôi đã đề xuất sẽ cho phép một người thực hiện nội tuyến, như vậy:encoding = cast_away_optional[ ENCODING_RE.search[line], ].groups[][0].decode['ascii']
Có vẻ như sử dụng một khẳng định sẽ yêu cầu thêm nhiều hơn.
Được rồi, mặc dù mong muốn làm điều này nội tuyến thay vì sử dụng một tuyên bố riêng biệt làm cho mong muốn yếu hơn rất nhiều. Đó là một con dốc trơn trượt; Python có các điều kiện nội tuyến, các vòng lặp [toàn diện] và bây giờ [trong 3,8] bài tập, nhưng không phải là những thứ khác như thử/ngoại trừ, trong khi, del, hoặc, thực sự, khẳng định ...
Nhưng không phải những thứ khác như cố gắng/ngoại trừ, trong khi, del, hoặc, thực sự, khẳng định ...
Thật vậy .. thực sự, đề xuất chỉ là thêm một cách trọng lượng nhẹ để nói với người kiểm tra loại rằng một cái gì đó không phải là không có [điều này không tự động yêu cầu sử dụng Assert]. Sử dụng
def is_null[arg: object] -> bool: # A silly function that dynamically checks for null and empty values return not arg class C: # Some class with some method def meth[self] -> int: ... def foo[arg: Optional[C]] -> int: if is_null[arg]: return 0 return arg.meth[] # error: Item "None" of "Optional[C]" has no attribute "meth2 như là loại khó chịu vì ví dụ: Người gọi không cần phải biết rằng
arg = cast_away_optional[arg] reveal_type[arg] # Should print C, not Optional[C] return arg.meth[] # Should not be an error3 trả về
arg = cast_away_optional[arg] reveal_type[arg] # Should print C, not Optional[C] return arg.meth[] # Should not be an error4:
encoding = cast[ Match[bytes], ENCODING_RE.search[line], ].groups[][0].decode['ascii']
Và sử dụng
arg = cast_away_optional[arg] reveal_type[arg] # Should print C, not Optional[C] return arg.meth[] # Should not be an error5 yêu cầu thêm hai dòng bao gồm một bài tập [không thể sử dụng biểu thức gán vì PIP cần hỗ trợ các phiên bản cũ hơn]:
for line in data.split[b'\n'][:2]: if line[0:1] == b'#' and ENCODING_RE.search[line]: match = ENCODING_RE.search[line] assert match is not None encoding = match.groups[][0].decode['ascii'] return data.decode[encoding]
Nhưng nếu bạn muốn đóng cửa này, tôi sẽ không cảm thấy tồi tệ vì tôi có cơ hội để đưa ra trường hợp của mình. :]
Tôi đoán bạn có thể tự viết:
import pytest
'''Tests'''
def test_parse_full_port_range[]: # This passes
port_range = PortRange.parse["5-10"]
assert port_range.start == 5
assert port_range.end == 10
def test_parse_port_range_with_start_only[]: # This fails
port_range = PortRange.parse["5"]
assert port_range.start == 5
assert port_range.end == 5
if __name__ == "__main__":
pytest.main[[__file__]]
0[Untested.]
DKGI, CJERDONEK, M-ACIEK, Analog-Cbarber, Leonardon473, Heni, Kblebebak, Flniu, Mepcotterell, Onurctirtir và 3 phản ứng khác với Thumbs Up Emoji