コードは、バグがより少なく、応答性がより良く、スループットがより高く、保守性がより良くあるべきだと思います。他に何か?「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 2
a_testClassA.i_string = a_replacingString;
// the phase 3
a_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 1
testFunction (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 2
a_testClassA->i_string = a_replacingString;
// the phase 3
a_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 1
testFunction (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 sys
from typing import List
class TestClass:
def __init__ (a_this: "TestClass", a_string: str) -> None:
a_this.i_string: str
a_this.i_string = a_string
class Test1Test:
@staticmethod
def 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 1
testFunction (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 2
a_testClassA.i_string = a_replacingString
# the phase 3
a_testClassB = a_testClassA
# the phase 4
if __name__ == "__main__":
Test1Test.main (sys.argv)
l_integerA: int = 1
l_integerA: int = 1
l_integerB: int = l_integerA + 2
from collections import OrderedDict
from typing import Callable
from typing import Collection
from typing import Container
from typing import Dict
from typing import Iterable
from typing import Iterator
from typing import List
from typing import Optional
from typing import Set
from typing import Sized
from typing import Tuple
# The built-in non-container types Start
l_integer: int = 1
l_float: float = 1.1
l_bool: bool = True
l_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 Start
l_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 types
l_classA: "ClassA" = ClassA ("ABC") # 'ClassA' is a class with the one-string-argument constructor
# Making it optional
l_optionalInteger: Optional [int] = None
# The function types
l_function: Callable [ [int, int], Tuple [int, int]] = divmod
# Some implicit-interface types Start
l_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 Type
from typing import TypeVar
l_classBoundByClassB = TypeVar ("l_classBoundByClassB", bound="ClassB")
class ClassB:
def methodA (a_this: "ClassB", a_string: str) -> str:
return a_string
@classmethod
def methodB (a_class: Type [l_classBoundByClassB], a_string: str) -> str:
return a_string
from typing import TypeVar
T = TypeVar ("T")
def functionA (a_type: TypeVar) -> None: # A wrong usage
None
functionA (T) # A wrong usage
from typing import TypeVar
T = TypeVar ("T")
def functionB (a_type: T) -> object:
return a_type
l_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 TypeVar
T = TypeVar ("T")
def functionC (a_type: T) -> T:
return a_type
l_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 TypeVar
T = TypeVar ("T", bound="ClassA") # can represent only 'ClassA' and its any descendant
U = TypeVar ("U", "ClassA", "ClassB") # can represent only 'ClassA' or 'ClassB'
from typing import Type
from typing import TypeVar
class ClassC:
def __init__ (a_this: "ClassC", a_string: str) -> None:
a_this.i_string: str
a_this.i_string = a_string
def 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 Dict
class ClassD:
def __init__ (a_this: "ClassD", a_name: str) -> None:
a_this.i_name: str
a_this.i_name = a_name
def methodA (a_this: "ClassD") -> str:
return "From ClassD " + a_this.i_name
class 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_name
class 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_name
l_dictionary1: Dict [str, "ClassD"] = {"Key1": ClassDA ("Name1"), "Key2": ClassDB ("Name2"), "Key3": ClassDB ("Name3"), "Key4": ClassDA ("Name4")}
~
from typing import cast
l_elementKey: str
l_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 = 1
l_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 List
from typing import TypeVar
T = TypeVar ("T")
def functionE (*a_items: T) -> List [T]:
l_list: List [T] = []
l_item: T
for l_item in a_items:
l_list.append (l_item)
return l_list
l_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 List
from typing import Type
from typing import TypeVar
T = TypeVar ("T")
def functionF (a_type0: Type [T], *a_items: T) -> List [T]:
l_list: List [T] = []
l_item: T
for l_item in a_items:
l_list.append (l_item)
return l_list
l_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 Generic
from typing import TypeVar
T = TypeVar ("T")
class ClassE (Generic [T]):
def __init__ (a_this: "ClassE", a_t: T) -> None:
a_this.i_t: T
a_this.i_t = a_t
def methodA (a_this: "ClassE") -> T:
return a_this.i_t
python3 -m pip install mypy
from datetime import datetime
from typing import Generic
from typing import TypeVar
T = TypeVar ("T")
class ClassF (Generic [T]):
def __init__ (a_this: "ClassF", a_t: T) -> None:
a_this.i_t: T
a_this.i_datetime: datetime
a_this.i_t = a_t
a_this.i_datetime = datetime.now ()
def methodA (a_this: "ClassF") -> T:
return a_this.i_t
from datetime import datetime
from typing import Generic
from typing import TypeVar
T = TypeVar('T')
class ClassF (Generic [T]):
def __init__ (a_this: "ClassF", a_t: T) -> None:
a_this.i_t: T
a_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 TypeVar
T = 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