Python3.5ノート——第8章オブジェクト向けプログラミング
16318 ワード
Python3.5ノート
第8章オブジェクト向けプログラミング
オブジェクト向け用語の説明
クラスの定義
例:
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
class MyClass(object):
i = ' '
def f(self):
return 'hello world %s' % self.i
クラス定義の書き方:
クラスの使用
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
class MyClass(object):
i = ' '
def f(self):
return 'hello world %s' % self.i
my_class = MyClass()
print(' :',my_class.i)
print(' :',my_class.f())
出力:
:
: hello world
クラスの使用は、関数呼び出しよりも多くの操作を行います.
クラスの構築方法
Pythonでは、Init()メソッドは、オブジェクトのインスタンス化時に呼び出される特殊なメソッドです.この方法の書き方は、まず2つの下線を入力し、その後initを入力し、次に2つの下線を入力します.この方法は構造方法とも呼ばれます.クラスを定義するときに表示されない定義_Init()メソッドでは、デフォルトでは、パラメータのない構築メソッドが呼び出されます.例は次のとおりです.
class MyClass2(object):
i = 123
def __init__(self,name1,age1):
self.name = name1
self.age = age1
def f(self):
return 'hello %s,you are %s years old!' % (self.name,self.age)
my_class2 = MyClass2(' ','23')
print(' :',my_class2.name)
print(' :',my_class2.age)
print(' :',my_class2.f())
出力:
:
: 23
: hello ,you are 23 years old!
1つのクラスでは複数の構造メソッドを定義できますが、クラスをインスタンス化する場合は最後の構造メソッドのみをインスタンス化します.すなわち、後の構造メソッドは前の構造メソッドを上書きし、最後の構造メソッドのパラメータに基づいてインスタンス化する必要があります.1つのクラスで、1つの構築方法のみを定義することをお勧めします.
クラスのアクセス権
パブリック属性とメソッドへの直接アクセス
クラスの内部には属性とメソッドがあり、外部コードは属性とメソッドを直接呼び出すことができます.例は次のとおりです.
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print('hello %s,you are %s years old!' % (self.name,self.age))
stu = Student(' ','23')
stu.info()
stu.name = ' '
stu.age = '24'
stu.info()
出力:
hello ,you are 23 years old!
hello ,you are 24 years old!
プライベート属性の定義とアクセス方法
クラスの内部プロパティが外部からアクセスされないようにするには、プロパティ名の前に下線_を2つ追加します.Pythonでは、インスタンスの変数名が2つの下線で始まると、プライベート変数になり、内部のみアクセスでき、外部はアクセスできません.この場合、直接アクセスするとエラーが発生します.例は次のとおりです.
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def info(self):
print('hello %s,you are %s years old!' % (self.__name, self.__age))
stu = Student(' ','23')
stu.info()
stu.__name = ' '
stu.__age = '24
stu.info()
出力:
Traceback (most recent call last):
File "D:/pyspace/hellopython/Chapter8.py", line 60, in
stu.info()
File "D:/pyspace/hellopython/Chapter8.py", line 57, in info
print('hello %s,you are %s years old!' % (self.name,self.age))
AttributeError: 'Student' object has no attribute 'name'
この場合、クラスにget_を追加することでattrs()メソッドで、クラス内のプライベート変数を取得します.クラスにset_を追加できますattrs()メソッドで、クラス内のプライベート変数を変更します.例は次のとおりです.
class Student(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def info(self):
print('hello %s,you are %s years old!' % (self.__name,self.__age))
def get_name(self):
return self.__name
def set_name(self,name):
self.__name = name
def get_age(self):
return self.__age
def set_age(self,age):
self.__age = age
stu = Student(' ','23')
stu.info()
stu.set_name(' ')
print(' :',stu.get_name())
stu.set_age('24')
print(' ',stu.get_age())
出力:
hello ,you are 23 years old!
:
24
プライベートメソッドの定義とアクセス方法
メソッド名に下線を2つ付けることで、メソッドをプライベートメソッドとして定義できます.プライベートメソッドは外部コードから直接アクセスできず、クラス内で共通メソッドでのみ呼び出されます.例は次のとおりです.
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __info(self):
print('hello %s,you are %s years old!' % (self.name,self.age))
def foo(self):
self.__info()
stu = Student(' ','23')
stu.foo()
出力:
hello ,you are 23 years old!
継承
classを定義すると、既存のclassから継承できます.定義された新しいclassはサブクラス(SubClass)と呼ばれ、継承されたclassはベースクラス、親クラス、またはスーパークラス(BaseClass、Super Class)と呼ばれます.継承されたフォーマットは次のとおりです.
class DerivedClassName(BaseClassName):
statemnt-1
...
statement-n
構文classサブクラス名(ベースクラス名)を継承する場合、ベースクラス名はカッコ内に書き込まれ、メタグループに指定されます.特徴は以下の通りである.
class Animal(object):
def run(self):
print('animal is running....')
class Dog(Animal):
pass
class Cat(Animal):
pass
dog = Dog()
dog.run()
cat = Cat()
cat.run()
出力:
animal is running....
animal is running....
子クラスは、親のプライベートメソッドを継承することも、親のプライベートメソッドを呼び出すこともできません.
マルチステート
子クラスと親クラスが同じメソッドを持つ場合、子クラスのメソッドは親クラスのメソッドを上書きし、メソッド呼び出し時に常に子クラスのメソッドを最初に呼び出します.これがマルチステートです.例は次のとおりです.
#! /user/bin/python3
# -*- coding:UTF-8 -*-
class Animal(object):
def run(self):
print('animal is running....')
class Dog(Animal):
def run(self):
print('dog is running....')
class Cat(Animal):
def run(self):
print('cat is running...')
dog = Dog()
dog.run()
cat = Cat()
cat.run()
print('dog animal ',isinstance(dog,Animal))
print('dog dog ',isinstance(dog,Animal))
出力:
dog is running....
cat is running...
dog animal True
dog dog True
例えば、上記の例では、dogとcatはそれぞれanimalを継承し、それぞれ独自のrunメソッドを定義し、最後にそれぞれのrunメソッドを呼び出す.
マルチステートを使用する利点は、Dog、Catなどのサブクラスオブジェクトを入力する必要がある場合、親のAnimalオブジェクトを受信するだけでよいことです.Dog、CatなどはAnimalタイプなので、Animalタイプに従ってパラメータを入力すればよいからです.Animalタイプにはrun()メソッドがあるため、入力されるタイプはAnimalクラスまたはAnimalのサブクラスであれば、インスタンスタイプのメソッドが自動的に呼び出されます.
多重継承
前節では単一継承について述べ,Pythonは多重継承もサポートしている.多重継承クラスは次のように定義されます.
class DerivedClassName(Base1,Base2,Base3):
statment-1
...
statement-n
多重継承は、複数のベースクラス(親またはスーパークラス)があることがわかります.
カッコ内の親の順序に注意してください.親に同じメソッド名がある場合、子の使用時に指定されていない場合、Pythonは左から右に検索されます.メソッドが子クラスに見つからない場合は、親クラスにこのメソッドが含まれているかどうかを左から右に検索します.
オブジェクト情報の取得
type()関数の使用
判断基本タイプはtype()関数で判断できます.次のようになります.
print('-----------type() -----------')
print(type('abc'))
print(type(123))
print(type(None))
print(type(abs))
print(type('abc')==str)
print(type(123)==int)
print('----------- -----------')
import types
def func():
pass
print(type(func)==types.FunctionType)
print(type(abs)==types.BuiltinFunctionType)
print(type(lambda x,y,z:x+y+z)==types.LambdaType)
print(type(x for x in range(1,10))==types.GeneratorType)
出力:
-----------type() -----------
True
True
----------- -----------
True
True
True
True
isinstance()関数の使用
isinstance()関数を使用すると、オブジェクトが何らかのタイプであるかどうかを教えてくれます.
print('dog animal ',isinstance(dog,Animal))
print('dog dog ',isinstance(dog,Animal))
しゅつりょく
dog animal True
dog dog True
dir()関数の使用
オブジェクトのすべてのプロパティとメソッドを取得するにはdir()関数を使用します.dir()関数は、文字列のlistを返します.次のようになります.
print(dir('abc'))
出力:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
クラスの独自の方法
_str_
Javaのto_に相当string()メソッド.次のようになります.
class Student(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def __str__(self):
return ' :%s, :%s' % (self.__name,self.__age)
print(Student(' ','23'))
stu_abc = Student(' ','24')
print(stu_abc)
出力:
: , :23
: , :24
注意:str_メソッドは文字列を返さなければなりません
_iter_
クラスをforに使用する場合は...inループはlistやtupleのように1つの_を実現しなければならない.iter_()メソッド.このメソッドは反復オブジェクトを返します.Pythonのforループは反復オブジェクトを呼び出し続けます.next()メソッドは、StopIterationエラーが発生したときにループを終了するまで、ループの次の値を取得します.次のようになります.
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1 # a、b
def __iter__(self):
return self # ,
def __next__(self):
self.a, self.b = self.b, self.a + self.b #
if self.a > 100000: #
raise StopIteration();
return self.a #
for n in Fib():
print(n)
出力:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
_getitem()_
リストのように下付き文字で要素を取り出すには、_getitem()_メソッドの例は次のとおりです.
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
print(Fib()[3])
出力:
3
_getattr_
使用_getattr_メソッドはプロパティを動的に返します.次のようになります.
class Student1(object):
def __getattr__(self, attr):
if attr == 'score':
return 95
stu1 = Student1()
print(stu1.score)
出力:
95
_call_
クラス定義を指定します.callメソッドでは、インスタンスを直接呼び出して結果を得ることができます._callはパラメータを定義することもできます.インスタンスを直接呼び出すと、1つの関数を呼び出すように、オブジェクトを関数と見なし、関数をオブジェクトと見なすことができます.この二つにはもともと根本的な違いはないからだ.オブジェクトを関数と見なすと、クラスのインスタンスが実行中に作成されるため、関数自体が実行中に動的に作成されます.これにより,オブジェクトと関数の境界がぼやけてしまう.例は次のとおりです.
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
class Student(object):
def __init__(self,name):
self.name = name
def __call__(self, *args, **kwargs):
print(' :%s' % self.name)
stu2 = Student(' ')
stu2()
出力:
:
Callable()関数を使用して、オブジェクトが呼び出されるかどうかを判断できます.例は次のとおりです.
print(callable(Student(' ')))
print(callable(Student1()))
print(callable(max))
print(callable([1,2,3]))
出力:
True
False
True
False
牛刀小试--旅の提案
サトシは今日出かけたいのですが、今日の天気が外出に適しているかどうかは分かりません.彼にアドバイスを提供するプログラムが必要です.プログラムのアドバイスはdaytimeとnightを入力し、視認度と温度によって移動のアドバイスと使用の交通手段を提供し、需要の変更の可能性を考慮する必要があります.
需要分析:本章で学んだパッケージ、継承、マルチステートを使用すると実現しやすく、親パッケージから可視度と温度を表示する方法で、子が親を継承します.必要に応じて、子クラスは親クラスのメソッドを上書きし、独自の実装を行うことができます.サブクラスはメソッドをカスタマイズすることもできます.
class WeatherSeach(object):
def __init__(self,input_daytime):
self.input_daytime = input_daytime
def search_visible(self):
visible = 0
if self.input_daytime == 'daytime':
visible = 6
elif self.input_daytime == 'night':
visible = 2
return visible
def search_temperature(self):
temperature = 0
if self.input_daytime == 'night':
temperature = 16
elif self.input_daytime == 'daytiem':
temperature = 26
return temperature
class OutAdvice(WeatherSeach):
def __init__(self,input_daytime):
WeatherSeach.__init__(self,input_daytime)
def search_temperature(self):
we_use = 'none'
if self.input_daytime == 'daytime':
we_use = ' '
elif self.input_daytime == 'night':
we_use = ' '
return we_use
def take_advice(self):
we_use = self.search_temperature()
visible = self.search_visible()
if visible >= 6:
print(' , %s ' % we_use)
elif 0 < visible <= 2:
print(' , %s ' % we_use)
else:
print(' , !')
oa = OutAdvice('night')
oa.take_advice()
しゅつりょく
,
質問の回答
二重下線の先頭のインスタンス変数は必ず外部からアクセスできませんか?
答え:いいえ、直接アクセスできないのはPython解釈器が外部にscore変数が_になりましたStudent__scoreですので、Student_scoreアクセス変数_score.次のようになります.
class Student(object):
def __init__(self,name,score):
self.__name = name
self.__socre = score
def info(self):
print(' :%s, :%s' % (self.__name,self.__socre))
def get_score(self):
return self.__socre
stu3 = Student(' ','94')
stu3.info()
#print(' :',stu3._Student__score) #
print(' :',stu3.get_score())
出力:
: , :94
: 94
メソッドと関数の違い
答え:Pythonでは、関数はクラスに依存せず、クラスで定義されていません.メソッドはクラスに依存し、クラスで定義され、本質的には関数です.区別を容易にするために,クラス内の関数をメソッドと呼び,クラスに依存しない関数を関数と呼ぶ.
クラスを使用する理由
Pythonでは、継承、カプセル化、多態の3つの特性を借りて、クラスを使用して1つの実物をよりよく管理することができ、同じ機能と行為を持つ物事を1つのクラスにカプセル化することができ、他の同じ特性を持つものは直接クラスを継承することができ、親のカプセル化の良い方法を得ることができます.同時に、サブクラスは親のメソッドを上書きして、特定の機能要件を満たすことができ、サブクラスは自分の機能を拡張することができます.クラスを使用すると、コードの多重化と拡張がよりよく実現されます.