Python 3オブジェクト向け-クラスとインスタンス


目次
1:Pythonのクラスの定義:
2:Pythonのクラスの例:
3:Python 3の擬似プライベート属性:
4:propertyプロパティ:
4.1内蔵関数property
4.2 setterとdleter装飾器
5:静的メソッドとクラスメソッド:
5.1:静的方法
5.2:クラスメソッド
Pythonではすべてがオブジェクトであり,Pythonは設計当初からオブジェクト向けの言語であった.
オブジェクト向けの3つの特徴:1:カプセル化:同じ属性と機能を持つコンテンツを1つのオブジェクトにカプセル化する.2:継承:子は、親のプライベート属性以外のすべてのコンテンツを自動的に所有できます.3:マルチステート:同じオブジェクトで、複数の形態を持つことができ、pythonはオリジナルでマルチステート性を備えています.
次のシリーズでは、この3つの特徴からPythonのオブジェクト向けを紹介します.
1:Pythonのクラスの定義:
形式は次のとおりです.
class name(superclass,...):   #  def    Class          
    attr = value       #    
    def method(...):   #       ( self  )
        pass

    #    
    @classmethod
    def clsMethod(cls):  # cls    
        print(cls)
        obj = cls()  #          
        print('   ')


    def method(self,...):  #       ( self  )
        self.attr = value  #     

PythonのClass文は宣言式ではなく、defと同様にClass文はオブジェクトの作成者であり、暗黙の付与演算である.def文と同様に、Class文も真の実行可能コードであり、つまりClass文を実行する前に定義されたクラスは存在しません.Class文を実行すると、変数名nameのオブジェクト(つまりクラス名)が作成されます.このオブジェクトには独自のプロパティとメソッド(クラスプロパティ、クラスメソッド)があり、ある呼び出しによって他のオブジェクト(つまりインスタンス)を作成できます.
Class文では、どの付与文でもクラス属性が生成されます.クラス名.プロパティで割り当てられた文にもクラスプロパティが生成されます.
要点:a:Class文は宣言ではなく、暗黙の付与であり、クラス名は変数名である.b:Class文にはクラスメソッド、クラスプロパティ、インスタンスメソッド(クラス名ネーミングスペースの下にあるプロパティ)、インスタンスプロパティ(クラス名ネーミングスペースの下にないプロパティ)、クラスメソッド.クラスプロパティはクラスインスタンスによって共有されます.c:Class文では、どの付与文でもクラス属性が生成されます.類名で属性=xx形式の付与によってクラス属性も生成されます.d:Pythonでは、クラス内のすべての属性とメソッドがpublicである(_,_の先頭の属性はPublicであり、偽プライベートと見なすことができる)とともに、クラス内のすべてのメソッドがvirtualである.
2:Pythonのクラスの例:
クラスはインスタンスファクトリであり、他の複数のインスタンスを作成できます.クラス属性とクラスメソッドはクラスに存在し、複数のインスタンスで共有できます.
Class文内のインスタンスメソッドでself.属性=xxx方式で付与された属性はすべてクラスのインスタンスに属し、複数のインスタンスには独立しています.
例1.属性1=xx形式の付与は、インスタンス1にのみ属性を追加し、他のインスタンスとは関係ありません.
サンプルコード:
# encoding=gbk

class Person:    #       (         ),Person        ,     person_1 = Person('  ',45)          
    country  = '  '
    #     
    @staticmethod
    def printCountry():
        print(Person.country)

    #    ,
    @classmethod
    def clsMethod(cls):  # cls    
        print(cls)
        obj = cls()  #          
        print('   ')



    def __init__(self,name,age):  #  Person      ,        ,
        self.name = name  #      
        self.age = age

    def setBirthday(self,birthday):
        self.birthday = birthday

    def PrintBirthday(self):
        print('self.birthday=', self.birthday)

    def printName(self):
        print('self.name=',self.name)

# __dict__         
print(Person.__dict__)
person_1 = Person('  ',18)
person_2 = Person('  ',19)
print(person_1.__dict__)  # {'name': '  ', 'age': 18}
print(person_2.__dict__)  # {'name': '  ', 'age': 19}
print(Person.__dict__)    #         ;         ,    Person    

print('---01--:'+'*'*60)
# 1:    ,     ,                 。(            )
Person.A1 = 'test_a1'
person_1.A2 = 'test_a2'
person_2.A3 = 'test_a3'

Person.B1 = 'test_B1_Person'
person_1.B1 = 'test_B1_Person1'
person_2.B1 = 'test_B1_Person2'

person_1.setBirthday('1990-10')
print(person_1.__dict__)  # {'name': '  ', 'age': 18, 'A2': 'test_a2', 'B1': 'test_B1_Person1', 'birthday': '1990-10'}
print(person_2.__dict__)  # {'name': '  ', 'age': 19, 'A3': 'test_a3', 'B1': 'test_B1_Person2'}    person_2    setBirthday,    birthday  
print(Person.__dict__)    #        'A1': 'test_a1', 'B1': 'test_B1_Person'

print('---02--:'+'*'*60)
# 2:    ,     (           ):            ,            ,                ,        ,     。
print(Person.A1)  #    test_a1
print(person_1.A1) #   test_a1,person_1       A1 ,               
print(person_2.A1) #   test_a1  person_2        A1 ,               

print(Person.B1)  #     test_B1_Person
print(person_1.B1) #    test_B1_Person1,person_1      B1
print(person_2.B1) #    test_B1_Person2,person_2      B1

print('---03--:'+'*'*60)
# 3:    
#    :          
Person.printCountry()
# person_1.printCountry()  #      
# person_2.printCountry()  #      

#     :      ,      +        
person_1.printName()
person_2.printName()
# Person.printName()  #         ,          ,  :
Person.printName(person_1)  #     person_1.printName()       
Person.printName(person_2)

print('---03--:'+'*'*60)
# 4:    ,     ,                   。(            )
#        ,           
def add(a,b):
    return a+b
person_2.add = add  #
print(person_2.add(10,19))

print(person_1.__dict__)  # {'name': '  ', 'age': 18, 'A2': 'test_a2', 'B1': 'test_B1_Person1', 'birthday': '1990-10'}
print(person_2.__dict__)  # {'name': '  ', 'age': 19, 'A3': 'test_a3', 'B1': 'test_B1_Person2', 'add': }
print(Person.__dict__)    #        add  

# Person.add(person_2,10,18)        ,add  person_2   

#         ,        

# def add(a,b):
#     return a+b
# Person.add = add  #               
# print(person_1.add(10,19))

#               。
def add2(aaa,a,b):
    print(aaa)  #  aaa   Person     
    return a+b
Person.add2 = add2  #               
print(person_1.add2(100,19))
#            ,  add2  Person          
print(Person.add2(person_1,200,30))


3:Python 3の擬似プライベート属性:
Python 3では,クラス内のすべての属性が共通であるpublicである.ただしPython 3では二重下線(_)先頭の属性は、偽のプライベートとして表現されます.
コードは以下の通りです.(このような偽プライベートを実現する方法については後述します)
# encoding=gbk

class Person:
    def __init__(self,name,age):
        #      (__)       ,        ,        :_  _  (   _Person__name),
        #        .__name              ,       __name       ,
        #           ._Person__name        
        self.__name = name
        self._age = age

print(Person.__dict__)  

p = Person('ixusy88',18)
print(p.__dict__)  # {'_Person__name': 'ixusy88', '_age': 18}
# print(p.__name)  # AttributeError: 'Person' object has no attribute '__name'  ,   __name    
print(p._Person__name)  #          ixusy88
print(p.__dict__['_Person__name']) #          ixusy88

4:propertyプロパティ:
4.1内蔵関数property
attribute = property(fget,fset,fdel,doc)
コード:
# encoding=gbk

class Person:
    def __init__(self,name):
        self._name = name

    def getName(self):
        print('get')
        return self._name

    def setName(self, value):
        print('set',value)
        self._name = value

    def delName(self):
        print('del',self._name)
        del self._name

    name = property(getName,setName,delName,'name property')

p = Person('ixusy88')
print('1:' + '*'*20)
print(p.name)
print('2:' + '*'*20)
p.name = '100'
print(p.name)
print('3:' + '*'*20)
del p.name

4.2 setterとdleter装飾器
# encoding=gbk
class Person:
    def __init__(self,name):
        self._name = name
    @property
    def name(self):
        print('get')
        return self._name

    @name.setter
    def name(self, value):
        print('set',value)
        self._name = value

    @name.deleter
    def name(self):
        print('del',self._name)
        del self._name

p = Person('ixusy88')
print('1:' + '*'*20)
print(p.name)
print('2:' + '*'*20)
p.name = '100'
print(p.name)
print('3:' + '*'*20)
del p.name

5:静的メソッドとクラスメソッド:
クラスには、selfインスタンスオブジェクトを転送する(デフォルト)静的メソッド:追加のオブジェクトを転送しない(staticmethodを介して)クラスメソッド:クラスオブジェクトを転送する(classmethodを介して)
5.1:静的方法
例:統計インスタンスの数:
# encoding=gbk

#     ,       
class Test:
    InstancesNums = 0
    def __init__(self):
        Test.InstancesNums = Test.InstancesNums + 1

    @staticmethod
    def printInstancesNums():
        print(f'InstancesNums is {Test.InstancesNums}')

class Sub(Test):
    pass

t = Test()
t = Test()
t = Test()
s = Sub()
Test.printInstancesNums()
t.printInstancesNums()
s.printInstancesNums()

5.2:クラスメソッド
統計クラスインスタンス数:
# encoding=gbk

#     ,       
class Test:
    InstancesNums = 0
    def __init__(self):
        Test.InstancesNums = Test.InstancesNums + 1

    @classmethod
    def printInstancesNums(cls):
        print(f'InstancesNums is {cls.InstancesNums}')

class Sub(Test):
    @classmethod
    def printInstancesNums(cls):
        print(f'InstancesNums is {cls.InstancesNums}')

class Other(Test):
    pass

t = Test()
t = Test()
o = Other()
s = Sub()
Test.printInstancesNums()
t.printInstancesNums()
Sub.printInstancesNums()
Other.printInstancesNums()

クラスごとのインスタンス数を統計します.
# encoding=gbk

#     ,       
class Test:
    InstancesNums = 0
    def __init__(self):
        self.count()

    @classmethod
    def count(cls):
        cls.InstancesNums += 1

    @classmethod
    def printInstancesNums(cls):
        print(f'InstancesNums is {cls.InstancesNums}')

class Sub(Test):
    InstancesNums = 0

    def __init__(self):
        super().__init__()

    @classmethod
    def printInstancesNums(cls):
        print(f'InstancesNums is {cls.InstancesNums}')

class Other(Test):
    InstancesNums = 0
    pass


t = Test()
o = Other()
o = Other()

s = Sub()
s = Sub()
s = Sub()

Test.printInstancesNums()
Other.printInstancesNums()
Sub.printInstancesNums()