Python学習ノート10:対象に向かってステップアップして終了
10322 ワード
1. __slots__変数#ヘンスウ# Pythonは動的言語であるため、通常、動的言語はプログラムの実行時に使用できます. オブジェクトに新しい属性またはメソッド をバインドするはまた、バインドされた属性および方法のバインド解除 を行うことができる.
カスタムタイプのオブジェクトを特定する必要がある場合は、クラスで__を定義することで、特定のプロパティのみをバインドできます.slots__変数を定義します. 注意:_slots__の定義は、現在のクラスのオブジェクトにのみ有効であり、サブクラスには何の役にも立たない.
2.静的メソッドとクラスメソッド以前、クラスで定義されたメソッドはすべてオブジェクトメソッドであり、すなわち、これらのメソッドはすべてオブジェクトに送信されるメッセージであった. 実際には、クラスに書く方法はすべてオブジェクトメソッドである必要はありません.たとえば、次のようにします. 「三角形」クラスを定義し、3つの辺長を伝達することによって三角形を構築し、周長と面積を計算する方法 を提供する.しかし、入力された3つの辺長は必ずしも三角形オブジェクトを構築できるとは限らないので、まず3つの辺長が三角形を構成できるかどうかを検証する方法を書くことができます.この方法は、この方法を呼び出すときに三角形オブジェクトがまだ作成されていないため(3つの辺が三角形を構成できるかどうか分からないため) ではありません.であるため、この方法は三角形クラスに属するが、三角形オブジェクトに属さない である.
静的手法を用いてこのような問題を解決することができる: は静的メソッドと比較的類似しており、Pythonはクラス内でクラスメソッドを定義することもできます. クラスメソッドの最初のパラメータ規則名はcls である.現在のクラスに関する情報のオブジェクト(クラス自体もオブジェクトであり、クラスのメタデータオブジェクトとも呼ばれる場合がある) を表す.このパラメータにより、クラスに関する情報を取得することができ、クラスのオブジェクト を作成することができる.
3.クラス間の関係簡単に言えば、クラスとクラスの関係は3つあります.is-a、has-a、use-aの関係です. s-a関係(継承または汎化)、例えば学生と人の関係、携帯電話と電子製品の関係は継承関係に属する. has-a関係(関連)、例えば部門と従業員の関係、自動車とエンジンの関係は関連関係に属している. 集約関係:関連関係が全体と部分の関連である場合. 合成関係:全体がさらに部分のライフサイクルを担当している場合(全体と部分は分割不可能であり、同時に同时に消滅する)、このような最も強い関連関係である.
use-a関係(依存)、例えば運転手が運転する行為(方法)があり、その中で(のパラメータ)が自動車に使用されると、運転手と自動車の関係は依存関係である.
UML(統合モデリング言語)を使用してオブジェクト向けモデリングを行うことができます.重要な作業の一つは、クラスとクラスの関係を標準化されたグラフィックシンボルで記述することです.
4.継承とマルチステート先ほど述べたように、既存のクラスに基づいて新しいクラスを作成することができます.この1つの方法は、あるクラスが別のクラスから属性と方法を直接継承し、重複コードの作成を減らすことです. 継承情報を提供するものを親と呼び、スーパークラスまたはベースクラスとも呼ぶ. 継承情報を得たものをサブクラス、派生クラスまたは派生クラスとも呼ぶ. 子クラスは、親が提供する属性とメソッドを継承するだけでなく、独自の属性とメソッドを定義することもできるので、子クラスは親よりも多くの能力を持つ .リ氏置換の原則:実際の開発では、親オブジェクトをサブクラスオブジェクトで置換することがよくあります.これは、オブジェクト向けプログラミングでよく見られる動作 です.リッツ置換原則の内容は、「派生クラス(サブクラス)オブジェクトは、そのベースクラス(スーパークラス)(親)オブジェクトの代わりにプログラム内で置換することができる」と記述することができる.
次に継承の例を見ます: サブクラスは、親のメソッドを継承した後、親の既存のメソッドに新しい実装バージョンを与えることができ、この動作をメソッド書き換え(override)と呼ぶ. メソッド書き換えにより、親の同じ動作をサブクラスで異なる実装バージョンにすることができ、このサブクラス書き換えメソッドを呼び出すと、異なるサブクラスオブジェクトが異なる動作を示すことができます.これがマルチステートです. のコードでは、Petクラスを抽象クラスに処理しました. 抽象クラスとはオブジェクトを作成できないクラスであり、このクラスの存在は他のクラスに を継承させるためである.
Pythonは文法的にJavaやC#のように抽象クラスのサポートを提供していませんが、abcモジュールのABCMetaメタクラスやabstractmethodパッケージを通じて抽象クラスの効果を達成することができます. クラスに抽象メソッドが存在する場合、このクラスはインスタンス化(オブジェクトの作成)できない .
上のコードでは、DogとCatの2つのサブクラスがPetクラスのmake_voice抽象メソッドは書き換えられ、異なる実装バージョンが与えられました. main関数でメソッドを呼び出すと、このメソッドはマルチステート挙動(同じメソッドで異なることをした) を示す.
総合ケース1(給与決済システム):
class Student(object):
# tuple
# Student name age
__slots__ = ('name', 'age')
class GraduateStudent(Student):
pass
s = Student() #
s.name = 'Jackson' # 'name'
s.age = 20 # 'age'
# s.score = 100
# ERROR: AttributeError: 'Student' object has no attribute 'score'
# slots , :
g = GraduateStudent()
g.score = 100
print('g.score =', g.score) # g.score = 100
2.静的メソッドとクラスメソッド
from math import sqrt
class Triangle(object):
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
#
@staticmethod
def is_valid(a, b, c):
return a + b > c and b + c > a and a + c > b
def perimeter(self):
return self._a + self._b + self._c
def area(self):
half = self.perimeter() / 2
return sqrt(half * (half - self._a) *
(half - self._b) * (half - self._c))
def main():
a, b, c = 3, 4, 5
#
if Triangle.is_valid(a, b, c):
t = Triangle(a, b, c)
print(t.perimeter())
#
# print(Triangle.perimeter(t))
print(t.area())
# print(Triangle.area(t))
else:
print(' .')
if __name__ == '__main__':
main()
# 12
# 6.0
from time import time, localtime, sleep
class Clock(object):
""" """
def __init__(self, hour=0, minute=0, second=0):
self._hour = hour
self._minute = minute
self._second = second
# :
@classmethod
def now(cls):
ctime = localtime(time())
return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)
def run(self):
""" """
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._minute = 0
self._hour += 1
if self._hour == 24:
self._hour = 0
def show(self):
""" """
return '%02d:%02d:%02d' % \
(self._hour, self._minute, self._second)
def main():
#
clock = Clock.now()
while True:
print(clock.show())
sleep(1)
clock.run()
if __name__ == '__main__':
main()
3.クラス間の関係
4.継承とマルチステート
# :
class Person(object):
""" """
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
def play(self):
print('%s Python.' % self._name)
def watch_mv(self):
if self._age >= 18:
print('%s .' % self._name)
else:
print('%s 《 》 .' % self._name)
# :
class Student(Person):
""" """
def __init__(self, name, age, grade):
super().__init__(name, age)
self._grade = grade
@property
def grade(self):
return self._grade
@grade.setter
def grade(self, grade):
self._grade = grade
def study(self, course):
print('%s %s %s.' % (self._grade, self._name, course))
# :
class Teacher(Person):
""" """
def __init__(self, name, age, title):
super().__init__(name, age)
self._title = title
@property
def title(self):
return self._title
@title.setter
def title(self, title):
self._title = title
def teach(self, course):
print('%s%s %s.' % (self._name, self._title, course))
def main():
stu = Student(' ', 15, ' ')
stu.study(' ')
stu.watch_mv()
t = Teacher(' ', 25, ' Boss')
t.teach(' Python ')
t.watch_mv()
if __name__ == '__main__':
main()
# .
# 《 》 .
# Boss Python .
# .
from abc import ABCMeta, abstractmethod
class Pet(object, metaclass=ABCMeta):
""" """
def __init__(self, nickname):
self._nickname = nickname
#
@abstractmethod
def make_voice(self):
""" """
pass
class Dog(Pet):
""" """
def make_voice(self):
print('%s: ...' % self._nickname)
class Cat(Pet):
""" """
def make_voice(self):
print('%s: ... ...' % self._nickname)
def main():
pets = [Dog(' '), Cat(' '), Dog(' ')]
for pet in pets:
pet.make_voice()
if __name__ == '__main__':
main()
# : ...
# : ... ...
# : ...
総合ケース1(給与決済システム):
"""
、
,
1. 15000
2. , 150
3. 1200 5%
"""
from abc import ABCMeta, abstractmethod
class Employee(object, metaclass=ABCMeta):
""" """
def __init__(self, name):
"""
:param name:
"""
self._name = name
@property
def name(self):
return self._name
@abstractmethod
def get_salary(self):
"""
:return:
"""
pass
class Manager(Employee):
""" """
def get_salary(self):
return 15000.0
class Programmer(Employee):
""" """
def __init__(self, name, working_hour=0):
super().__init__(name)
self._working_hour = working_hour
@property
def working_hour(self):
return self._working_hour
@working_hour.setter
def working_hour(self, working_hour):
self._working_hour = working_hour if working_hour > 0 else 0
def get_salary(self):
return 150.0 * self._working_hour
class Salesman(Employee):
""" """
def __init__(self, name, sales=0):
super().__init__(name)
self._sales = sales
@property
def sales(self):
return self._sales
@sales.setter
def sales(self, sales):
self._sales = sales if sales > 0 else 0
def get_salary(self):
return 1200.0 + self._sales * 0.05
def main():
emps = [
Manager(' '), Programmer(' '),
Manager(' '), Salesman(' '),
Salesman(' '), Programmer(' '),
Programmer(' ')
]
for emp in emps:
if isinstance(emp, Programmer):
emp.working_hour = int(input(' %s : ' % emp.name))
elif isinstance(emp, Salesman):
emp.sales = float(input(' %s : ' % emp.name))
# get_salary ( )
print('%s : ¥%s ' %
(emp.name, emp.get_salary()))
if __name__ == '__main__':
main()