Pythonの学習日記5
- クラスとオブジェクト(2)
404昨日、1日は、子どもたちにどのようなしなかったが、また、いくつかの疑問に杜漏、今日の答えを学習します。
最後にオブジェクトは何ですか?
物体の存在は、特定のエンティティである;例えば、「車種」はその後、「ジープ」、「オートバイ」はオブジェクトで、クラスであり、私たちは、抽象クラスは、オブジェクトのグループ、クラスは概念に抽象化することが可能である、と言います我々は、オブジェクトではなく、人間である人について話しています。
時間のほとんどは、クラスの同じ複数のオブジェクトが同じ特性を持っているクラスの繰り返しのオブジェクトを作成するクラスを定義しますが、クラスは複数のオブジェクトの共通の特徴を定義します。特定の観点から、定義されたクラスは、複数のオブジェクトに特徴付けられ、したがってない特定のクラスエンティティが存在する場合、オブジェクトは特定のエンティティの存在です。
それから私は無意味始めました。直接メソッドを呼び出すために、クラスの名前を使用しないで、なぜ私は取りつかれをオフにリッピングし始めていますか?昨日は本当に夢遊病され、今日もそれをよくお読み?404いいえ見つかり
実際には、すべてのPythonプログラム処理は、抽象と具象の間の差がちょうど良く2つだけではなく、その定義との間の関係を理解するために、オブジェクトの種類です。関数と同様、Pythonでモジュールやクラスなどのプログラミングユニットは、彼らは、このような文と式デフ、クラス、インポートおよびラムダによって作成され、自由に他のオブジェクトに保存されているスクリプト、間で渡すことができ、オブジェクトです。
(グースはZhendi愚かである、悪はまた夢を見て少しJAVA人、授業時間を学んだのですか?..ダム)
4.2方法
この方法は、抽象クラスまたはオブジェクトの行動特性であるが、この方法は、実際にPythonの関数であり、定義された方法および機能は非常に類似しています。
4.2.1クラスもインスタンスメソッドを呼び出すことができます
デフォルト定義されたPythonクラスメソッドがインスタンスメソッドは、オブジェクトを作成した後、オブジェクトを介して呼び出すことができ、インスタンスメソッドです。
Pythonのクラスは、名前空間が好きです。Pythonはグローバル名前空間内の既定のプログラムであり、クラスベースの材料は、名前空間内にあります。Pythonはグローバルに実行可能なコード、クラスの範囲内に放置し、実行可能なコードベースの材料を放置しました。
# 定义全局空间的fun函数
def fun():
print("全局空间内的fun方法")
# 定义全局空间内的bar变量
bar = 20
#-------------------
class ssalc:
# 定义类体内的fun函数
def fun(self):
print("类体空间内的fun方法")
# 定义类体内的bar变量
bar=2000
#----------------------
# 调用全局空间的函数和变量
fun()
print(bar)
# 调用类空间内的函数和变量
s=ssalc()
ssalc.fun(s)
print(s.bar)
Pythonのクラスのインスタンスメソッドを呼び出すことができるが、インスタンスを呼び出すクラスのメソッドを使用して、Pythonは自動的にパラメータにパラメータ値を結合する自己方法ではない、プログラムは、明示的に、最初のパラメータとして呼び出し元メソッドに渡されなければなりません。上記のコードの最後のケース。次のコードはエラーになりますように:
ssalc.fun()
TypeError: fun() missing 1 required positional argument: 'self'
私はここに円をオフにリッピングしていたところがあり、なぜ直接呼び出しにクラス名を使用していますが、実際のパラメータ渡しの問題は発生しません。
4.2.2クラスメソッド、および静的メソッド
Pythonはさえ静的メソッドの定義をサポートする、クラスメソッドの定義をサポートしています。クラスメソッドと静的メソッドは、その差があることで、非常に似ています。Pythonは自動的に自動的にクラス自体にバインドされている最初の引数のクラスメソッド、最初のパラメータのクラスメソッド(通常は名前のCLS)に結合する;しかし、静的なためこの方法は、自動的に結合されていません。
@classmethod修飾方法は、クラスメソッドであり、
使用が修正された方法は、静的メソッドである@staticmethod。
class player:
@classmethod
def classM(cls):
print('类方法:',cls)
@staticmethod
def staticM(p):
print('静态方法:',p)
#调用类方法,player类会自动绑定到第一个参数
player.classM()
#调用静态方法,不会自动绑定,需要手动绑定
a=player()
a.classM() #类方法不需要手动绑定
#用对象调用staticM静态方法,实际上依然还是使用类来调用的
#必须为第一个参数执行手动绑定
a.staticM('hello')
4.2.3 @関数デコレータ
上記と@staticmethodは、クラスメソッドとstaticmethodパイソンが内蔵される機能、本質的に装飾的な機能を、@classmethod。
他の機能を変更するために使用することができ、既存の機能を参照するために、@記号を使用して、装飾的な機能を変更しました。
別の装飾「B機能」プログラム「@Aによって機能」を使用する場合は、実際には、以下の2つのステップを完了しました。
- Bは、@記号の参照Aの関数の関数へのパラメータとして変更されます。
- 装飾的な機能は、最初のステップで値Bを返します。
def funA(fn):
print('A')
return 'fkit'
@funA #相当于把funB作为funA的参数,funA(funB)
def funB():
print('B')
print(funB)
A
fkit #因为funA的返回值是fkit,所以此时funB=fkit,
# funB相当于被替换成了字符串
関数は、@記号は非常に便利な機能であることにより、修正、両方のパーミッションチェックの機能として変更前にいくつかの追加の処理ロジックを追加し、ロギング機能の後に修正され、いくつかの追加の処理ロジックを追加してもよいれますあなたはまた、いくつかの修復操作対象のメソッド例外を行うことができます。
三オブジェクト指向言語機能:ポリモーフィズム、継承とカプセル化:
4.3以上の状態
アヒルタイプ:多型は、Pythonプログラミングモードのコア、そのための面白い名前が呼ばれるのです。これは、ことわざから来ている:「それはアヒルのように歩き、アヒルのように鳴く、それはアヒルであれば。」
あなたはそれを行うことができます種類の操作の何、オブジェクトの種類が分からない場合は、職場での多型です。Pythonの変数の宣言は、新しい変数の型を必要とせず、変数を直接使用することができ、別の例は、文字列の数の両方を使用することもできる「+」加算演算子であり、多型は、マスタと呼ばれることもあれば識別するために、ターゲット文字列を表現することができるのrepr関数は、()、物体の長さの関数を示すように構成することができます。
def length_fun(x):
print('The length of',repr(x),is,len(x)
この関数は、任意のオブジェクトの任意の出力に適用されます。
あなたは、マルチ状態を破棄したい場合は、唯一の方法は、このようなタイプ、issubclass、でisinstanceおよびその他の機能として、明示的な型チェックを使用することであるが、実際には、それ自体issubclass多形性アップです。
4.4パッケージ
パッケージ(封入)は、不要な詳細を隠蔽外部を指します。
これは、彼らがあるため、オブジェクトの内部の詳細を知らなくてもあなたは、二つの概念が好きで、それを実行することができ、同じ多型であるように思わ抽象的な原則。
カプセル化は客観的世界では、オブジェクトのステータス情報は、外の世界を直接操作し、変更することはできません、オブジェクトの内部に隠されている、客観的世界のオブジェクト指向言語のシミュレーションです。オブジェクトまたはパッケージのクラスは、これらの目的を達成するために実施することができます。
- クラスの背後にある実装の詳細
- 所定の方法により予めデータへのアクセスのみを許可し、制御ロジックはプロセスに追加することができ、アクセス属性無理限界。
- データの整合性を確認することができ、オブジェクトは、情報を確実にするのに役立ちます
- 変更するのは簡単、容易な保守コード
優れたカプセル化のニーズを実現するためには二つの側面から考慮すべき:
- オブジェクト属性と非表示の実装の詳細は、外部への直接アクセスを許可していません。
- この方法は、これらの属性と操作へのアクセスを制御するので、安全な方法を公開しました。
同じ服HHHHを身に着けているように、露にさらされる皮の所持、
Pythonは本当に隠さサポートすることはできませんので、JAVAおよびPythonは、同じpriviate修飾子を提供していません。Pythonのメソッドが隠されている:二重下線付きのクラス名が始まるのメンバーは、Pythonはそれらを非表示になります。
class User :
def __hide(self):
print('示范隐藏的hide方法')
def getname(self):
return self.__name
def setname(self, name):
if len(name) < 3 or len(name) > 8:
raise ValueError('用户名长度必须在3~8之间')
self.__name = name
name = property(getname, setname)
def setage(self, age):
if age < 18 or age > 70:
raise ValueError('用户名年龄必须在18在70之间')
self.__age = age
def getage(self):
return self.__age
age = property(getage, setage)
# 创建User对象
u = User()
u.name = 'fkit'
# 引发 ValueError: 用户名长度必须在3~8之间
Userクラスのインスタンス変数は__nameと__age 2は隠れていた、()のみSETNAME()、のgetName()、setage()、getageを通じて、直接、これらのアクセサメソッドをこれらの変数にアクセスすることはできません。このプログラムアクセス、およびsetage()、SETNAME()のみの資格がセットに許可されている、年齢のコントロールを、ユーザーの名前を設定します。
上記のコードは、次のコードを呼び出すプログラムの試みがエラーをスローする場合は、デフォルトで隠され__hide()メソッドを定義します。
#尝试调用隐藏的__hide()方法
u.hide()
AttributeError: 'User' object has no attribute '__hide'
しかし、Pythonは、実際には本当の隠ぺいメカニズム、二重下線ほんの少しトリックではありません:Pythonは密かにメソッド名をダブルアンダースコアに変更するには、以下の方法に従って呼び出すことができますので、それは、メソッド名の前に、単一のアンダースコアとクラス名を追加します:(しかし、通常は行いません)
# 调用隐藏的__hide()方法
u._User__hide()
4.5クラスの継承
継承は、怠惰な重要な手段です。Pythonの継承はサブクラスが、同時により多くの直接の親を持つことができていること、複数の継承メカニズムです。
4.5.1継承の構文
Pythonの構文サブクラス継承親クラスをサブクラスが複数のサブクラスの後の括弧内に、親クラスで定義されている、あなたはサブクラスは親クラスを継承することを示すことができます。
class SubClass(SuperClass1,SuperClass2,...):
#定义部分
、Objectクラスから、このクラスの継承をクラスを定義するとき、あなたが明示的に疲れた親を指定しない場合は、そう言って、Objectクラスは、すべてのクラスの親クラスで、直接的または間接的な親の親クラス。
通常、親クラスが大サブクラスが含まれているよりも、スコープ、サブクラスを展開するには、サブクラスに親クラス、親クラスで、サブクラスは親の特別な種類です。
4.5.2オーバーライド親クラス
親クラスごとに合計のサブクラスで、ほとんどの時間、そして親に展開されますが、サブクラスは親クラスがどちらかの偉大な親は長江が古い、サブクラスに取って代わる適切なサブクラスではないということではないことも可能です親クラスのメソッドを書き換える必要があります。
class Driver:
# Driver类的fly()方法
def driver(self):
print("我会开拖拉机...")
class Ostrich(Driver):
# 重写Driver类的driver()方法
def driver(self):
print("我会开大卡车,挖掘机,拖拉机,直升机...")
# 创建Ostrich对象
os = Ostrich()
# 执行Ostrich对象的driver()方法,将输出"我会开大卡车,挖掘机,拖拉机,直升机..."
os.driver()
このサブクラスはまた、屋根付きメソッドと呼ばれる現象が知らメソッドのオーバーライド(上書き)、と親クラスのメソッドと同じ名前を備えています。
4.5.3使用未結合の方法は、オーバーライドされたメソッドを呼び出します
メソッドの呼び出しサブクラスに書き換えた後、Pythonは必ずサブクラスでメソッドをオーバーライドし、実行する場合に書き換えることが必要で、クラスに子供の父親を呼び出すことができるならば、書き換えられた親クラスのメソッドは、実行されませんこの方法は、あなたが電話を呼び出すために、クラス名を使用することができるとき。
class BaseClass:
def foo (self):
print('父类中定义的foo方法')
class SubClass(BaseClass):
# 重写父类的foo方法
def foo (self):
print('子类重写父类中的foo方法')
def bar (self):
print('执行bar方法')
# 直接执行foo方法,将会调用子类重写之后的foo()方法
self.foo()
# 使用类名调用实例方法(未绑定方法)调用父类被重写的方法
BaseClass.foo(self)
sc = SubClass()
sc.bar()
4.5.4スーパーコンストラクタ関数は、親クラスを呼び出します
サブクラスが複数の親クラスを有する場合にはPythonのサブクラスにも継承された親クラスのコンストラクタは、親クラスの構築方法の上部表面は、例えば、に使用されます。
class Employee :
def __init__ (self, salary):
self.salary = salary
def work (self):
print('普通员工正在写代码,工资是:', self.salary)
class Customer:
def __init__ (self, favorite, address):
self.favorite = favorite
self.address = address
def info (self):
print('我是一个顾客,我的爱好是: %s,地址是%s' % (self.favorite, self.address))
# Manager继承了Employee、Customer
class Manager (Employee, Customer):
pass
#m = Manager(25000)
m = Manager('IT产品', '广州')
#m.work() #代码1
m.info() #代码2
クラスで定義されているマネージャークラスのコードは、従業員が前に立っているため、従業員や顧客のクラスを継承していますので、彼のコンストラクタの使用を優先させて頂きます。だから、マネージャー(2500)マネージャでオブジェクトを作成しているプログラムが好きなとアドレス2つの変数を初期化していなかったので、1がコードを実行することができますが、コード2がエラーになりますので、この方法では、インスタンス変数の給料を初期化します。
マネージャは、同時に2つの親クラスを開始できるためには、それはそれ自身のコンストラクタを定義する必要があります - 親クラスのコンストラクタを書き換えることです。Pythonの要件:子クラスが親クラスのコンストラクタをオーバーライドする場合は、サブクラスのコンストラクタは、親クラスのコンストラクタを呼び出す必要があります。2つの方法があります。
- 結合していないメソッドを使用します
- ()関数のスーパーを使用すると、親クラスのコンストラクタを呼び出します
スーパークラスは、実際には、それは、オブジェクトのスーパー、スーパークラスを作成するためにコンストラクタを呼び出すことですスーパーエッセンスを呼び出します。
最も一般的に使用されるスーパー()コンストラクタメソッドは、任意のパラメータを渡していない場合、オブジェクトのメソッドはスーパーインスタンスメソッド呼び出しの親クラスとすることができる使用して、クラスの親クラスを呼び出すことができます。。あなたは、インスタンスメソッドを呼び出すと、クラスのメソッドを呼び出すと、最初の引数のCLSの結合を完了しますときに最初の引数の自己結合を完了します。
そして、上記の手順は次の形式に変更されます。
class Manager(Employee, Customer):
# 重写父类的构造方法
def __init__(self, salary, favorite, address):
print('--Manager的构造方法--')
# 通过super()函数调用父类的构造方法
# super().__init__(salary)
# 与上一行代码的效果相同
super(Manager, self).__init__(salary)
# 使用未绑定方法调用父类的构造方法
Customer.__init__(self, favorite, address)
# 创建Manager对象
m = Manager(25000, 'IT产品', '广州')
m.work() #①
m.info() #②
5.6 Pythonの動的な
クラス、オブジェクト、プロパティ、メソッドを動的に追加および変更することができます:Pythonはで、動的な言語です。
5.6.1動的プロパティと__slots__
動的オブジェクトのメソッドを使用すると、すべてのインスタンスメソッドを追加したい場合は、この方法は、クラスを追加するだけでなく、いくつかのリスクをもたらすことによって達成することができ、現在のオブジェクトに対してのみ有効です追加します。
あなたは、プロパティ__slots__を指定するために使用できる動的なプロパティとメソッドの制限を増やしたい場合。
class Dog:
__slots__ = ('walk', 'age', 'name')
def __init__(self, name):
self.name = name
def test():
print('预先定义的test方法')
d = Dog('Snoopy')
from types import MethodType
# 只允许动态为实例添加walk、age、name这3个属性或方法
d.walk = MethodType(lambda self: print('%s正在慢慢地走' % self.name), d)
d.age = 5
d.walk()
#如果尝试添加其他属性,那么会报错
d.foo = 30 # AttributeError
注2点があります。
- __slots__クラスのプロパティやメソッドによって動的に追加のプロパティに限られるものではありません
- __slots__現在のクラスのインスタンスのみが動作する属性、派生サブクラスは、サブクラスで__slots__プロパティを再定義する必要がありますに影響はありません。
5.6.2使用メタクラス
あなたはバッチクラスを作成したい場合は#すべての特定の特性がmataclassによって達成することができる持っています。クラスを作成するときに動的にクラス定義を変更するために使用するメタクラス。
動的クラス定義メタクラスを変更するために、プログラムが最初にメタクラスを定義する必要があり、メタクラスは、クラスタイプを継承し、及びリライタブル__new __()メソッドべきです。
動的にクラスを作成するには、5.6.3の使用タイプ()
タイプ()関数は、変数の型を表示するために使用することができます。
class Role:
pass
r = Role()
# 查看变量r的类型
print(type(r)) # <class '__main__.Role'>
# 查看Role类本身的类型
print(type(Role)) # <class 'type'>
目に見える、クラス自体のタイプがタイプです。
プログラムはクラスを作成するクラスを使用すると、特別なオブジェクト(オブジェクト型クラス)を定義するものとして理解され、ロール変数にオブジェクトをコピーするために話すことができ、クラス定義とクラスのすべてのインスタンスが型クラスです。
動的タイプ()関数でクラスを作成することが可能です。
def fn(self):
print('fn函数')
# 使用type()定义Dog类
Dog = type('Dog', (object,), dict(walk=fn, age=6))
# 创建Dog对象
d = Dog()
# 分别查看d、Dog的类型
print(type(d))
print(type(Dog))
d.walk()
print(Dog.age)
<class '__main__.Dog'>
<class 'type'>
fn函数
6
あなたはタイプを使用してクラスを作成する場合は()3つのパラメータを指定することができます。
- クラス名は、作成:パラメータ
- コレクション継承された親クラス:パラメータ二
- パラメータIII:辞書オブジェクトのクラス変数とクラスバインディングの方法。
講義の内部怒っパイソンとの直接いくつかのコード、本当に書きたくない
明日良い評価ああでなければならない
自閉症アップ。。。。。。。。。。。。。
自閉症。。。。。。。。。。。。。
自閉症。。。。。。。。。。。。。