pythonオブジェクト向けプログラミングステップ(7)

4980 ワード

  • は、クラスのプロパティにいくつかの制限を加えることができ、__slots__のプロパティを宣言する必要があります.一般的には、クラス自体のプロパティのみが制限されます.継承関係がある場合、子の親にこの属性がある場合、親は自身の影響を受け、子は親の制限を受け、二重の影響を受ける.親にはこの属性があり、子にはないので、親は自身の影響を受け、子は影響を受けません.子クラスにはこの属性があり、親クラスにはありません.親クラスも子クラスも影響を受けません.
  • プライベート変数について、getter、setterの方法を簡略化する.
  • は、いくつかの方法(例えば、__str____repr__など)の用途について簡単に紹介する.

  • 例と注釈を直接見ます.
    class Person:
        #   Person    name、age  ,   tuple  
        __slots__ = ('name', 'age')
    
        # print(p)     ,      __str__  ,   <__main__.person object="" at="">
        #      ,          。
        def __str__(self):
            return 'Person object (name: %s)' % self.name
    
        #      p ,      
        __repr__ = __str__
    
        def do(self):
            print('person...')
    
    
    class Student(Person):  
        __slots__ = ('sex',)
    
    
    p = Person()
    p.name = 'tom'
    print(p.name)
    print(p)
    
    s = Student()
    s.age = 23
    print(s.age)
    
    
    class Teacher:
    
        def __init__(self, name):
            self._name = name
    
        #   getter  ,      
        @property
        def name(self):
            # _name        ,     self.name
            return self._name
    
        #   setter  ,  @property  ,   @   .setter   
        @name.setter
        def name(self, name):
            if isinstance(name, str):
                self._name = name
            else:
                raise ValueError('str is required')
    
    
    t = Teacher('fuck')
    print(t.name)
    t.name = 'tom'
    print(t.name)
    

    継承する場合、主線は一般的に単一に継承されます.拡張機能が必要な場合は、追加の機能クラスを設計し、多重継承すればよい.この設計は一般にMixInと呼ばれる.例:
    #  
    class RunnableMixIn:
        def do(self):
            print('run...')
    
    #  
    class FlyMixIn:
        def do(self):
            print('fly...')
    
    #    ,                   ,              。                 。
    class My(Person, FlyMixIn, RunnableMixIn):
        pass
    
    
    m = My()
    m.do()
    

    オブジェクト定義をlistのようにデータを操作するには、次の方法を定義します.
    #       
    class Fib:
    
      def __init__(self):
         self.a = 0
         self.b = 1
    
      #         ,    __iter__ __next__  
      def __iter__(self):
          return self
    
      def __next__(self):
          self.a, self.b = self.b, self.a + self.b
          return self.a
    
      #     list        ,    __getitem__  
      # item     ,    slice  ,    list       ,      
      #        dict,item    key
      def __getitem__(self, item):
         if isinstance(item, int):
             a, b = 1, 1
             for i in range(item):
                 a, b = b, a + b
             return a
         elif isinstance(item, slice):
             # start stop     ,         
            start = item.start
            if start is None:
              start = 0
            stop = item.stop
            value = []
            a, b = 1, 1
            for i in range(stop):
                if i >= start:
                  value.append(a)
                a, b = b, a + b
            #       
            step = item.step
            new_value = []
            if step is not None and step != 1:
                for i in range(len(value)):
                    if i * step < len(value) - 1:
                        new_value.append(value[i * step])
                return new_value
            else:
                return value
    
      #           
      def __setitem__(self, key, value):
          pass
    
      #            
      def __delitem__(self, key):
          pass
    
      #    get          ,   ,   __getattr__               
      #           ,              
      def __getattr__(self, item):
          if item == 'c':
              return 100
    
    for v in Fib():
      if v < 100:
          print(v)
      else:
          break
    
    print(Fib()[2])
    print(Fib()[:10])
    print(Fib()[:10:2])
    print(Fib().c)
    

    チェーンコール、定義_getattr__()と_call__()メソッド、urlの組み立てに便利
    class Chain:
    
          def __init__(self, path=''):
              self._path = path
    
          #    .      ,     
          def __getattr__(self, path):
              return Chain('%s/%s' % (self._path, path))
    
          def __str__(self):
              return self._path
    
          __repr__ = __str__
    
          #     ()      
          def __call__(self, args):
              return Chain('%s/%s' % (self._path, args))
    
    
    print(Chain().status.user.timeline.list) -->   :/status/user/timeline/list
    print(Chain().users('michael').repos) -->   :/users/michael/repos
    # callable(obj)   obj   callable,class     __call__  ,      
    print(callable(Chain())) -->   :True
    print(callable([1, 2])) -->   :False
    print(callable(max)) -->   :True
    

    type()関数は、変数または関数のタイプを表示できます.
    #    class type
    print(type(Chain))
    #    class Chain
    print(type(Chain()))
    

    type(args 1,args 2,args 3)関数は、クラスを作成することもできます.
    Args 1:クラス名args 2:親tuple args 3:クラス内のメソッド名バインドメソッドではclass Xxx宣言クラスが一般的であり、Python解釈器がclass定義に遭遇した場合、class定義の構文をスキャンしてtype()メソッドを呼び出してclassを作成するだけであるため、動的言語Python自体はランタイム動的classの作成をサポートする.
    def fn(self, name='233'):
        print('name: %s' % name)
    
    #    
    Test = type('Test', (object,), dict(test=fn))
    # name: HelloTest
    Test().test('HelloTest')