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')