コードは、バグがより少なく、応答性がより良く、スループットがより高く、保守性がより良くあるべきだと思います。他に何か?「Pythonic」であるべきですか?
話題
About: Python
#include <iostream>#include <string>class TestClass {public:::std::string & i_string;TestClass (::std::string & a_string);virtual ~TestClass ();TestClass & operator= (const TestClass & a_TestClass);};TestClass::TestClass (::std::string & a_string): i_string (a_string) {}TestClass::~TestClass () {}TestClass & TestClass::operator= (const TestClass & a_TestClass) {i_string = a_TestClass.i_string;return *this;}class Test1Test {public:static int main (int const & a_argumentsNumber, char const * const a_arguments []);};void testFunction (TestClass & a_testClassA, TestClass & a_testClassB, ::std::string & a_replacingString) {// the phase 2a_testClassA.i_string = a_replacingString;// the phase 3a_testClassB = a_testClassA;// the phase 4}int Test1Test::main (int const & a_argumentsNumber, char const * const a_arguments []) {::std::string l_stringA ("A");::std::string l_stringB ("B");::std::string l_stringC ("C");TestClass l_testClassA = TestClass (l_stringA);TestClass l_testClassB = TestClass (l_stringB);// the phase 1testFunction (l_testClassA, l_testClassB, l_stringC);::std::cout << "### 'l_testClassA': " << l_testClassA.i_string << ", " << "'l_testClassB': " << l_testClassB.i_string << ::std::endl;return 0;}
### 'l_testClassA': C, 'l_testClassB': C
#include <iostream>#include <string>class TestClass {public:::std::string * i_string;TestClass (::std::string * a_string);virtual ~TestClass ();TestClass & operator= (const TestClass & a_TestClass);};TestClass::TestClass (::std::string * a_string): i_string (a_string) {}TestClass::~TestClass () {}TestClass & TestClass::operator= (const TestClass & a_TestClass) {i_string = a_TestClass.i_string;return *this;}class Test1Test {public:static int main (int const & a_argumentsNumber, char const * const a_arguments []);};void testFunction (TestClass * a_testClassA, TestClass * a_testClassB, ::std::string * a_replacingString) {// the phase 2a_testClassA->i_string = a_replacingString;// the phase 3a_testClassB = a_testClassA;// the phase 4}int Test1Test::main (int const & a_argumentsNumber, char const * const a_arguments []) {::std::string * l_stringA = new ::std::string ("A");::std::string * l_stringB = new ::std::string ("B");::std::string * l_stringC = new ::std::string ("C");TestClass * l_testClassA = new TestClass (l_stringA);TestClass * l_testClassB = new TestClass (l_stringB);// the phase 1testFunction (l_testClassA, l_testClassB, l_stringC);::std::cout << "### 'l_testClassA': " << *(l_testClassA->i_string) << ", " << "'l_testClassB': " << *(l_testClassB->i_string) << ::std::endl;delete l_testClassA;delete l_testClassB;delete l_stringA;delete l_stringB;delete l_stringC;return 0;}
### 'l_testClassA': C, 'l_testClassB': B
import sysfrom typing import Listclass TestClass:def __init__ (a_this: "TestClass", a_string: str) -> None:a_this.i_string: stra_this.i_string = a_stringclass Test1Test:@staticmethoddef main (a_arguments: List [str]) -> None:l_stringA: str = "A"l_stringB: str = "B"l_stringC: str = "C"l_testClassA: "TestClass" = TestClass (l_stringA)l_testClassB: "TestClass" = TestClass (l_stringB)# the phase 1testFunction (l_testClassA, l_testClassB, l_stringC)sys.stdout.write ("### 'l_testClassA': " + l_testClassA.i_string + ", " + "'l_testClassB': " + l_testClassB.i_string + "\n")def testFunction (a_testClassA: "TestClass", a_testClassB: "TestClass", a_replacingString: str) -> None:# the phase 2a_testClassA.i_string = a_replacingString# the phase 3a_testClassB = a_testClassA# the phase 4if __name__ == "__main__":Test1Test.main (sys.argv)
l_integerA: int = 1
l_integerA: int = 1l_integerB: int = l_integerA + 2
from collections import OrderedDictfrom typing import Callablefrom typing import Collectionfrom typing import Containerfrom typing import Dictfrom typing import Iterablefrom typing import Iteratorfrom typing import Listfrom typing import Optionalfrom typing import Setfrom typing import Sizedfrom typing import Tuple# The built-in non-container types Startl_integer: int = 1l_float: float = 1.1l_bool: bool = Truel_string: str = "ABC"l_bytes: bytes = b"ABC"l_classAClass: type = ClassAA # 'ClassAA' is a class.# The built-in non-container types End# The built-in container types Startl_list: List [int] = [1, 2]l_set: Set [float] = {1.1, 2.2}l_dictionary: Dict [bool, str] = {True: "ABC", False: "DEF"}l_elementsOrderPreservedDictionary: "OrderedDict [bytes, int]" = OrderedDict ({b"DEF": 2, b"ABC": 1})l_tuple: Tuple [float, ...] = (1.1, 2.2, 3.3, )# The built-in container types End# The user-defined class instance typesl_classA: "ClassA" = ClassA ("ABC") # 'ClassA' is a class with the one-string-argument constructor# Making it optionall_optionalInteger: Optional [int] = None# The function typesl_function: Callable [ [int, int], Tuple [int, int]] = divmod# Some implicit-interface types Startl_iterable: Iterable [int] = [1, 2]l_iterator: Iterator [int] = iter ([1, 2])l_sized: Sized = [1, 2]l_container: Container [int] = [1, 2]l_collection: Collection [int] = [1, 2]# Refer to 'https://mypy.readthedocs.io/en/stable/protocols.html' for the details of each implicit-interface type# Refer to 'https://mypy.readthedocs.io/en/stable/protocols.html' for the other predefined so-called "protocol" types (I call them 'implicit-interface types').# Some implicit-interface types End
from typing import Typefrom typing import TypeVarl_classBoundByClassB = TypeVar ("l_classBoundByClassB", bound="ClassB")class ClassB:def methodA (a_this: "ClassB", a_string: str) -> str:return a_string@classmethoddef methodB (a_class: Type [l_classBoundByClassB], a_string: str) -> str:return a_string
from typing import TypeVarT = TypeVar ("T")def functionA (a_type: TypeVar) -> None: # A wrong usageNonefunctionA (T) # A wrong usage
from typing import TypeVarT = TypeVar ("T")def functionB (a_type: T) -> object:return a_typel_object1: object = functionB ("ABC") # The 1st 'functionB' call checking is done on this line.l_object2: object = functionB (1) # The 2nd 'functionB' call checking is done on this line.
from typing import TypeVarT = TypeVar ("T")def functionC (a_type: T) -> T:return a_typel_string: str = functionC ("ABC") # The 1st 'functionC' call checking is done on this line.l_integer: int = functionC (1) # The 2nd 'functionC' call checking is done on this line.
from typing import TypeVarT = TypeVar ("T", bound="ClassA") # can represent only 'ClassA' and its any descendantU = TypeVar ("U", "ClassA", "ClassB") # can represent only 'ClassA' or 'ClassB'
from typing import Typefrom typing import TypeVarclass ClassC:def __init__ (a_this: "ClassC", a_string: str) -> None:a_this.i_string: stra_this.i_string = a_stringdef methodA (a_this: "ClassC") -> None:print ("From ClassC " + a_this.i_string)class ClassCA (ClassC):def __init__ (a_this: "ClassCA", a_string: str) -> None:ClassC.__init__ (a_this, a_string)def methodA (a_this: "ClassCA") -> None:print ("From ClassCA " + a_this.i_string)T = TypeVar ("T", bound="ClassC")def functionD (a_type: Type [T], a_string: str) -> T:return a_type (a_string)l_classC: ClassC = functionD (ClassC, "ABC")l_classCA: ClassCA = functionD (ClassCA, "ABC")
from typing import Dictclass ClassD:def __init__ (a_this: "ClassD", a_name: str) -> None:a_this.i_name: stra_this.i_name = a_namedef methodA (a_this: "ClassD") -> str:return "From ClassD " + a_this.i_nameclass ClassDA (ClassD):def __init__ (a_this: "ClassDA", a_name: str) -> None:ClassD.__init__ (a_this, a_name)def methodAA (a_this: "ClassDA") -> str:return "From ClassDA " + a_this.i_nameclass ClassDB (ClassD):def __init__ (a_this: "ClassDB", a_name: str) -> None:ClassD.__init__ (a_this, a_name)def methodAB (a_this: "ClassDB") -> str:return "From ClassDB " + a_this.i_namel_dictionary1: Dict [str, "ClassD"] = {"Key1": ClassDA ("Name1"), "Key2": ClassDB ("Name2"), "Key3": ClassDB ("Name3"), "Key4": ClassDA ("Name4")}
~from typing import castl_elementKey: strl_elementValue: "ClassD"for l_elementKey, l_elementValue in l_dictionary1.items ():if isinstance (l_elementValue, ClassDA):l_classDA: "ClassDA" = cast ("ClassDA", l_elementValue)print (l_classDA.methodAA ())if isinstance (l_elementValue, ClassDB):l_classDB: "ClassDB" = cast ("ClassDB", l_elementValue)print (l_classDB.methodAB ())
l_string: str = "ABC"l_integer: int = 1l_integer = cast (int, l_string)
~l_integer = cast (float, l_string)
l_object: object = "ABC"l_integer = cast (int, l_object)print (str (l_integer))
from typing import Listfrom typing import TypeVarT = TypeVar ("T")def functionE (*a_items: T) -> List [T]:l_list: List [T] = []l_item: Tfor l_item in a_items:l_list.append (l_item)return l_listl_list1: List [str] = functionE ("ABC", "DEF")l_list2: List [object] = functionE ("ABC", "DEF") # This does not cause any error, surprisingly.
functionE ("ABC", "DEF").append (1) # Still, this causes an error.
from typing import Listfrom typing import Typefrom typing import TypeVarT = TypeVar ("T")def functionF (a_type0: Type [T], *a_items: T) -> List [T]:l_list: List [T] = []l_item: Tfor l_item in a_items:l_list.append (l_item)return l_listl_list1: List [str] = functionF (str, "ABC", "DEF")l_list2: List [object] = functionF (object, "ABC", "DEF")l_list3: List [object] = functionF (str, "ABC", "DEF") # I am not happy about this behavior, but that seems unpreventable.functionF (object, "ABC", "DEF").append (1) # This does not cause any error.functionF (str, "ABC", "DEF").append (1) # An error, rightfully.
from typing import Genericfrom typing import TypeVarT = TypeVar ("T")class ClassE (Generic [T]):def __init__ (a_this: "ClassE", a_t: T) -> None:a_this.i_t: Ta_this.i_t = a_tdef methodA (a_this: "ClassE") -> T:return a_this.i_t
python3 -m pip install mypy
from datetime import datetimefrom typing import Genericfrom typing import TypeVarT = TypeVar ("T")class ClassF (Generic [T]):def __init__ (a_this: "ClassF", a_t: T) -> None:a_this.i_t: Ta_this.i_datetime: datetimea_this.i_t = a_ta_this.i_datetime = datetime.now ()def methodA (a_this: "ClassF") -> T:return a_this.i_t
from datetime import datetimefrom typing import Genericfrom typing import TypeVarT = TypeVar('T')class ClassF (Generic [T]):def __init__ (a_this: "ClassF", a_t: T) -> None:a_this.i_t: Ta_this.i_datetime: datetime...def methodA(a_this: ClassF) -> T: ...
# Stubs for ClassF (Python 3)## NOTE: This dynamically typed stub was automatically generated by stubgen.from typing import TypeVarT = TypeVar('T')class ClassF:def __init__(a_this: ClassF, a_t: T) -> None: ...def methodA(a_this: ClassF) -> T: ...
mypy %the source file path%
stubgen -o %the output directory% %the source file path%
[mypy][mypy-aaa.Aaa]ignore_missing_imports = True[mypy-aaa.Bbb]ignore_missing_imports = True