Pythonの合宿45日-Day07(高度なオブジェクト指向プログラミング)

前文:さらなる調査のために、我々は我々がするオブジェクト指向、この章の基礎を学んだ最後の章オブジェクト指向の知識

1. @propertyデコレータ

最後の章では、我々はプライベートにプロパティをお勧めしませんが、プロパティを直接外の世界に直接さらされている場合には、例えば、も問題ですが、我々は、プロパティへのアクセスの話をしているとき、我々は値がプロパティに割り当てられているかどうかを確認することはできません効果的。私たちは、財産が保護されていることを意味する、このように、単一のアンダースコアで始まる属性名の前にあることをお勧めしますが、プロパティには、我々は彼らを通過させることができない、論理検証方法である实例.属性行くためにも、時間の割り当てをロジックのセットは、我々は、プロパティを確認します。我々はそれをしたい場合は、私たちが使用する必要があります@propertygetterメソッドとsetterメソッドをラップするデコレータを

# -*- coding:utf-8 -*-
"""
@Property 装饰器
version:0.1
author:coke
"""
class Person(object):

    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    
    #访问器
    @property
    def name(self):
        return self.__name 
    
    #访问器 - getter方法
    @property
    def age(self):
        return self.__age
    
    @age.setter
    def age(self,age):
        if age < 0 or age > 150:
            print("年龄参数不正确")
            return
        self.__age = age
    
    def play(self):
        if self.__age <= 16:
            print("%s正在玩飞行棋."%self.__name)
        else:
            print("%s正在玩斗地主."%self.__name)

def main():
    person = Person("Jack",12)
    person.age = -1
    person.play()

if __name__ == "__main__":
    main()

出力

 

要約:@propertyパラメータの必要なチェックを確保しつつ、プログラムが実行されているように、広くエラーの可能性を低減する、発信者がショートコードを記述することができ、クラスの定義に使用されます

 

2.マジックメソッド

Pythonはある動的言語動的言語は、私たちがランニング中のオブジェクトにバインドする新しいプロパティやメソッドを許可する一般的に、当然のことながら、プロパティとメソッドがバインドされているバインド解除することができます。しかし、我々は唯一の特定のプロパティをバインドすることができ、オブジェクトのカスタムタイプを定義する必要がある場合、それはクラスで定義することができます__slots__変数を定義します。ことに注意してください__slots__現在定義されている唯一のオブジェクトは、サブクラスの発効のクラスはどんな役割を果たしていません。

# -*- coding:utf-8
"""
slots
version:0.1
author:coke
"""


class Person(object):
   # 限定Person对象只能绑定_name,_age 和 _gender属性
   __slots__ = ('_name', '_age', '_gender')

   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):
       if self._age <= 16:
           print("%s正在玩飞行棋,年龄%d" % (self._name, self._age))
       else:
           print("%s正在玩斗地主,年龄%d" % (self._name, self._age))

def main():
   person = Person("Jack",18)
   person.play()

if __name__ == "__main__":
   main()

概要:__slots__変数は、あなたがクラスのインスタンスの属性を制限することができますを追加することができます。

 

3.クラスおよびインスタンスのプロパティ

私たちが接触する前の例では、インスタンスの属性は、メモリ内のコピーは1つだけ公共のために、そこにある、それはすべてのオブジェクトのクラスのオブジェクトのインスタンスに共通する(オブジェクト属性)、定義により、クラス属性は、クラスオブジェクトが所有する財産ですクラス属性は、外部クラスのオブジェクトクラスとインスタンスは、オブジェクトにアクセスできる
 
クラス属性を

class People(object):
    address = "山东"
    def __init__(self):
        self.name = "xiaowang" #实例属性
        self.age = 20

p = People()
p.age = 12
print(p.address) #正确
print(People.address) #正确
print(p.name) #正确
print(p.age) #正确

print(People.address)#正确
#print(People.age) #错误
#print(People.name) #错误

要約:特性の例をすることはできません类对象.实例属性取得し、いずれかのクラスの属性を通じて类对象.类属性取得、またすることができます实例对象.类属性取得

 

一例として、(オブジェクト)は、クラスの属性を変更するには

class People(object):
    country = 'china' #类属性

print(People.country) #china
p = People()
print(p.country)  #china
p.country = "japan"
print(p.country) #japan
print(People.country) #china
del p.country
print(p.country) #china

要約:クラスの属性も、あなたはできますが实例对象.类属性、しかし、インスタンスオブジェクトクラスを変更し、同じ名前のオブジェクトの宣言のインスタンス場合、アクセスを削除するには、属性をすることはできません、プロパティがプロパティインスタンスのプロパティに属しています

 

4.静的メソッドとクラスのメソッド

前に、私たちは、これらのメソッドは、オブジェクトにメッセージを送信していること、クラスのメソッドは、オブジェクトのメソッドで定義します。必要に応じて実際には、我々はまた、静的メソッドとクラスメソッドを作成することができ、すべてのオブジェクトのメソッドを必要としないクラスメソッドで書きました

 
staticメソッド

"""
静态方法
version:0.1
author:coke
"""
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(t.area())
    else:
        print("无法构成三角形")

if __name__ == '__main__':
    main()
        

概要:デコレータことで@staticmethodクラスオブジェクトから直接呼び出すことができ、我々は静的メソッドと静的メソッドを呼び出す方法を変更します

 

クラスメソッド

"""
类方法
version:0.1
author:coke
"""
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):
        ctimes = localtime(time())
        return cls(ctimes.tm_hour, ctimes.tm_min, ctimes.tm_sec)

    def run(self):
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._hour += 1
                self._minute = 0
                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()

概要:修飾デバイスと@classmethodクラスメソッドは、クラスメソッドとしてそれを識別するために、最初のパラメータは、一般的に、クラスオブジェクトでなければならないclsパラメータは、CLSに等しいので、オブジェクトおよび実施例によりクラスオブジェクトにアクセスすることができ、得られた最初のパラメータとしてそのような情報への間接的なアクセス、私たちはしてクラスのオブジェクトクラスのメソッドを作成することができます

 

5.単一および複数継承

プログラムでは、継承は、猫や犬などの事、動物に属しているとの間の関係を属し説明、プログラムは動物から継承された猫や犬のように記述することができる。同様に、バリやペルシャ猫は猫から継承されており、以下に示すようにシャーペイとわんちゃんは、十分に継承します。

単一継承は、親クラスの情報を継承するだけでいい、多重継承は複数の親クラス情報を継承することでしたダイヤモンドの継承に起因する問題が存在しますので、ほとんどのプログラミング言語は、単一継承のみが許可されていることを知るために。しかし、パイソンが、事故で多重継承の出現できるようにする
 
単一継承を


# 继承object类父类信息
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正在愉快的玩耍."% self._name)

    def watch_tv(self):
        if self._age >= 18:
            print("%s 正在看刺激的电影"%self._name)
        else:
            print("%s 正在看熊出没"%self._name)
    
# (person) 继承person父类信息
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):
        self._grade = grade
    
    def study(self,course):
        print("%s的%s正在学习%s."%(self._grade,self._name,course))

#继承 person父类信息
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 teacher(self,course):
        print("%s%s正在讲%s."%(self._name,self._title,course))
    
def main():
    stu = Student("Jack",15,"初二")
    stu.study("数学")
    stu.watch_tv()
    t = Teacher("Marry",38,"专家教授")
    t.teacher("语文")
    t.watch_tv()

if __name__ == "__main__":
    main()    

出力

 

多重継承

#coding=utf-8
class base(object):
    def test(self):
        print('----base test----')
class A(base):
    def test(self):
        print('----A test----')

# 定义一个父类
class B(base):
    def test(self):
        print('----B test----')

# 定义一个子类,继承自A、B
class C(A,B):
    pass


obj_C = C()
obj_C.test()

print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序

出力

概要:コールするダイヤモンドの継承の問題、解決順序(依存MRO

 

6.ポリモーフィズム

サブクラスは親クラスを継承した後、既存の親クラスの実現の新しいバージョンを与えることができ、このアクションが呼び出されるメソッドのオーバーライド(上書き)。メソッドを書き換えることにより、我々は、親クラスの同じ動作は、我々はこのサブクラスが書き換えられたパスを呼び出すときに、達成するために、サブクラスで異なるバージョンを持っている、オブジェクトの異なるサブクラスは異なる挙動を示すことができます、これは、ポリモーフィズム(多型)。

"""
多态
version:0.1
author:coke
"""
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()

分析: ABCモジュールを使用する抽象クラスを実装し、abc.ABCMeta抽象基底クラスが実装するクラスである@abstractmethod機能を実現することなく、抽象メソッドの定義は、サブクラスは抽象クラス抽象クラスがオーバーライドしなければならない抽象メソッドを継承します。テンプレート法などの抽象メソッド

 

7.デル・メソッド

あなたがオブジェクトを作成した後、Pythonインタプリタはデフォルト呼び出す__init__()メソッドを、オブジェクトが削除されたとき、Pythonインタプリタは、デフォルトのメソッド呼び出しになり、この方法は、__del__()方法

import time
class Animal(object):
    #初始化方法
    #创建完对象后自动被调用
    def __init__(self,name):
        print("init方法被调用")
        self.__name = name
    
    #析构方法
    #当对象被删除时,会自动被调用
    def __del__(self):
        print("del方法被调用")
        print("%s对象马上被干掉了..."%self.__name)

dog = Animal("田园犬")
#删除对象
del dog

cat = Animal("波斯猫")
print("准备删除波斯猫了....")
del cat

出力

おすすめ

転載: www.cnblogs.com/dwlovelife/p/11593365.html