Python基礎之六面向物件高階程式設計
阿新 • • 發佈:2019-01-30
'''
面向物件高階程式設計
'''
from enum import Enum
'''
__slots__
限制例項屬性
定義的屬性只對當前類例項起作用,對於繼承的子類不起作用
'''
class Student(object):
__slots__ = ('name', 'age')
s = Student()#建立一個新的例項
s.name = '張三'#繫結屬性
s.age = 45
#s.score = 99,在__slots__中沒有score則不不能繫結
print(s.name)
'''
@propert
'''
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 200:
raise ValueError('score must between 0 ~ 200' )
self._score = value
s = Student()
s.score = 60#實際轉化為s.set_score(60)
print(s.score)#例項轉化為s.get_score()
'''
多重繼承
Python允許使用多重繼承
'''
'''
定製類
__str__
'''
'''
__str__
__repr__ 同上
__iter__
'''
class Student(object):
def __init__(self, name):
self.name = name
print(Student('張三' ))##預設列印方式
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name: %s)' % self.name
__pepr__ = __str__
print(Student('張三'))##複寫__str__方法列印方式
'''
__iter__
類似於想被for...in迴圈,必須實現一個__iter__()方法改方法返回一個迭代物件,然後
Python的for迴圈不斷呼叫改迭代對昂的__next__()方法迴圈到下一個值,知道遇到StopIteration錯誤退出迴圈
'''
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1#初始化兩個計數器a,b
def __iter__(self):
return self#例項本省就是迭代物件,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b #計算下一個值
if self.a > 100000:#退出迴圈條件
raise StopIteration()
return self.a#返回下一個值
def __getitem__(self, item):#想像list中一樣取出下標 必須實現__getitem__()方法
a, b = 1, 1
for x in range(item):
a, b = b, a + b
return a
for n in Fib():
print(n)
'''
__getitem__
想像list中一樣取出下標 必須實現__getitem__()方法
'''
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1#初始化兩個計數器a,b
def __iter__(self):
return self#例項本省就是迭代物件,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b #計算下一個值
if self.a > 100000:#退出迴圈條件
raise StopIteration()
return self.a#返回下一個值
def __getitem__(self, item):#想像list中一樣取出下標 必須實現__getitem__()方法
a, b = 1, 1
for x in range(item):
a, b = b, a + b
return a
f = Fib()
print(f[9])
'''
__getattr__
正常情況下,當我們呼叫類的方法或屬性時,如果不存在,就會報錯。
'''
class Student(object):
def __init__(self):
self.naame = "張三"
def __getattr__(self, item):#不存在時會返回99
if item == 'score':
return 99
s = Student()
print(s.name)
print(s.score)
'''
__call__
例項本身呼叫屬性和方法
'''
class Student(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('My name is %s.' % self.name)
s = Student("張三")
print(s())
'''
使用列舉類
'''
from enum import Enum
Month = Enum('Moth', ('Jan', 'Fen', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
print(Month.Mar.value)
from enum import Enum, unique
@unique
class Weekday(Enum):
Sun = 0#Sun的value被設定為0
Mon = 1
Tue = 2
Web = 3
Thu = 4
Fri = 5
Sat = 6
print(Weekday.Mon)
print(Weekday.Thu)
print(Weekday['Tue'])
print(Weekday(5))
'''
使用元類
'''
'''
type
動態語言和靜態語言的最大不同,就是函式和類的定義,不是編譯時定義的,而是執行時動態建立的
'''
class Hello(object):
def hello(self, name = 'world'):
print('Hello, %s.' % name)
h = Hello()
print(h.hello())
print(type(Hello))
print(type(h))
def fn(self, name = 'world'):#先定義函式
print('Hello, %s.' % name)
#建立一個class物件, type()函式一次傳入3個引數
#1class名稱
#2繼承的父類集合,注意Python支援多重繼承,如果只有一個父類,別忘了tuple的單元寫法,後面跟個','號
#3class的方法名稱與函式繫結,這裡我們把函式fn繫結到方法名為hello上.
Hello = type('Hello', (object,), dict(hello=fn))
h = Hello()
print(h.hello())
'''
metaclass
'''
class ListMetaclass(type):
#接收引數
#1當前準備建立的類的物件
#2類的名字
#3累積繼承的集合
#4類的方法集合
def __new__(cls, name, bases, attrs):
attrs['add'] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs)
class MyList(list, metaclass=ListMetaclass):
pass
L = MyList()
L.add(1)
print(L)