python---面向物件2
阿新 • • 發佈:2019-01-24
1構造方法與析構方法
from collections import Counter
class People(object):
# 例項化物件時自動執行
def __init__(self, name, age):
# 把屬性和物件名繫結在一起, 便於訪問物件的屬性.
self.name = name
self.age = age
print("建立物件成功.......")
# 解構函式, 當你刪除物件時, 自動呼叫的方法。
# del 物件名或者程式執行結束之後
def __del__(self):
print("刪除物件成功.......")
if __name__ == '__main__':
# 建立物件
p1 = People('fentiao', 12)
#
# del p1
2.物件str與repr方法
from collections import Counter
class People(object):
# 例項化物件時自動執行
def __init__(self, name, age):
# 把屬性和物件名繫結在一起, 便於訪問物件的屬性.
self.name = name
self.age = age
print("建立物件成功.......")
# 解構函式, 當你刪除物件時, 自動呼叫的方法。
# del 物件名或者程式執行結束之後
def __del__(self):
print("刪除物件成功.......")
# __str__和__repr__都是對物件的字串顯示, 使用場景不同.
# 如果沒有__str__的時候, 自動呼叫__repr__方法的內容.
def __str__(self):
# print(物件名) print(str(物件名))
# print('People(%s, %d)' %(self.name, self.age))
return 'People(%s, %d)' %(self.name, self.age)
def __repr__(self):
# print(repr(物件名)) 或者互動式環境中直接: 物件名
return "People(%s)" %(self.name)
def __hello(self):
print("hello")
def world(self):
self.__hello()
if __name__ == '__main__':
# 建立物件
p1 = People('fentiao', 12)
print(p1)
print(p1.__str__())
p1.world()
# print(str(p1))
# print(repr(p1))
3.圖書管理系統
# 假設每本書只有一本
class Book(object):
def __init__(self, name, author, state, bookIndex):
self.name = name
self.author = author
# 0:'已借出' 1:'未借出'
self.state = state
self.bookIndex = bookIndex
def __str__(self):
return 'Book(%s, %d)' %(self.name, self.state)
class BookManage(object):
# 存放所有書籍資訊, 列表裡面存放的是Book物件
books = []
def start(self):
"""圖書管理系統初始化資料"""
self.books.append(Book('python', 'Guido', 1, 'IN23445'))
self.books.append(Book('java', 'Guido1', 1, 'IN23445'))
self.books.append(Book('C++', 'Guido2', 1, 'IN23445'))
print("初始化資料成功!")
def Menu(self):
"""圖書管理選單欄"""
while True:
print("""
圖書管理操作
1). 新增書籍
2). 刪除資料
3). 查詢書籍
4). 退出
""")
choice = input("請輸入你的選擇:")
if choice == '1':
self.addBook()
elif choice == '2':
self.delBook()
elif choice == '3':
self.isBookExist('python')
elif choice == '4':
exit()
else:
print("請輸入正確的選擇!")
def addBook(self):
print("新增書籍".center(0, '*'))
name = input("書籍名稱:")
bObj = self.isBookExist(name)
if bObj:
print("書籍%s已經存在" %(bObj.name))
else:
self.books.append(Book(name,input("作者:"), 1, input("存放位置:")))
print("書籍%s新增成功" %(name))
def delBook(self):
pass
def borrowBook(self):
pass
def returnBook(self):
pass
def isBookExist(self, name):
"""檢測書籍是否存在"""
# 1. 依次遍歷列表books裡面的每個元素
# 2. 如果有一個物件的書名和name相等, 那麼存在;
# 3. 如果遍歷所有內容, 都沒有發現書名與name相同, 書籍不存在;
for book in self.books:
if book.name == name:
# 因為後面需要
return book
else:
return False
if __name__ == "__main__":
bManger = BookManage()
bManger.start()
bManger.Menu()
4.字串的format方法
print("name:%s, age:%d, scores:%s" % ('westos', 10, dict(a=1, b=2)))
print("name:%s, age:%d, scores:%s" % ('westos', 10, (1, 2)))
print("name:%s, age:%d, name:%s" % ('westos', 10, 'westos'))
# 通過位置填充字串
print("name:{0}, age:{1}, scores:{2}".format('westos', 10, [100, 100, 100]))
print("name:{0}, age:{1}, scores:{0}".format('westos', 10))
print("name:{0}, id:{1:.3f}, scores:{0}".format('westos', 19.2332435))
# 通過key值填充字串
d = {'max': 100, 'min': 10}
print("MAX: {max}, MIN:{min}".format(max=100, min=10))
print("MAX: {max}, MIN:{min}".format(**d))
# 通過下標或者索引值填充
point = (3,4)
print("x:{0[0]}, y:{0[1]}".format(point))
# 面向物件操作
class Book(object):
def __init__(self, name, author, state, bookIndex):
self.name = name
self.author = author
# 0:'已借出' 1:'未借出'
self.state = state
self.bookIndex = bookIndex
def __str__(self):
return 'Book(%s, %d)' %(self.name, self.state)
b = Book('python', 'guido', 1, 'IND444')
print("name:{b.name}, state:{b.state}, author:{b.state}".format(b=b))
print("name:{0.name}, state:{0.state}, author:{0.state}".format(b))
5.format魔術方法
formats = {
'ymd':"{d.year}-{d.month}-{d.day}",
'mdy':"{d.month}/{d.day}/{d.year}",
}
class Date(object):
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# format方法: format(物件名)時自動呼叫
def __format__(self, format_spec=None):
# return "這是顯示format的內容"
# if format_spec:
# format_spec = format_spec
# else:
# format_spec = 'ymd'
if not format_spec:
format_spec = 'ymd'
fmt = formats[format_spec] # "{d.year}-{d.month}-{d.day}".format(d=d)
return fmt.format(d=self)
d = Date(2019, 8, 25)
print(format(d))
print(format(d, 'mdy'))
# print(d.__format__('ymd'))
# print(format(d, 'ymd'))
# ‘ymd’ ===> ‘2019-8-25’
# ‘mdy’ ===> '8/25/2019'
format簡化版
class Date(object):
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# format方法: format(物件名)時自動呼叫
def __format__(self, format_spec=None):
if not format_spec:
return "%s-%s-%s" %(self.year, self.month, self.day)
else:
if format_spec == 'ymd':
return "%s-%s-%s" %(self.year, self.month, self.day)
elif format_spec == 'dmy':
return "%s/%s/%s" %(self.day, self.month, self.year)
else:
return "error format"
d = Date(2019, 8, 25)
print(format(d))
print(format(d, 'ymd'))
print(format(d, 'dmy'))
# print(d.__format__('ymd'))
# print(format(d, 'ymd'))
# ‘ymd’ ===> ‘2019-8-25’
# ‘mdy’ ===> '8/25/2019'
6.類內部裝飾器property
class Book(object):
def __init__(self, name, author, state, bookIndex):
self.name = name
self.author = author
# 0:'已借出' 1:'未借出'
self.__state = state
self.bookIndex = bookIndex
# 將類方法變成類屬性
# 使用時, 沒有裝飾器b.state()
# 使用時, 有裝飾器b.state
@property
def state(self):
if self.__state == 0:
return '已借出'
elif self.__state == 1:
return '未借出'
else:
return "狀態異常"
# 當修改屬性state時, 自動執行下面的方法; b.state = 10
@state.setter
def state(self, value):
# if value == 0 or value == 1:
if value in (0,1):
# 更新書籍的狀態
self.__state = value
@state.deleter
def state(self):
print("is deleteing......")
def __str__(self):
return 'Book(%s, %d)' %(self.name, self.__state)
b = Book('python', 'guido', 1, 'chddf')
# print(b.state)
#
# # 1). 書籍的狀態可以人以改變, 並不能限制只能為0或者1;
# 2). 書籍狀態如何友好的顯示?
# b.state = 10
# print(b.state)
# 3). 問題解決, 但是呼叫比較複雜, 可讀性不高.
# print(b.get_state())
# print(b.set_state(10))
# print(b.get_state())
# 4).
print(b.state)
b.state = 0
print(b.state)
del b.state
7.實現類的切片與索引
class Student(object):
def __init__(self, name, scores):
self.name = name
self.scores = scores
# 支援索引; s[index]
def __getitem__(self, index):
# print("獲取索引對應的value值")
return self.scores[index]
# s[索引] = 修改的值
def __setitem__(self, index, value):
self.scores[index] = value
# del s[索引]
def __delitem__(self, index):
del self.scores[index]
def hello(self):
return "hello"
s = Student('westos', [101, 100, 100])
# *********************************index**************************
# print(s[0])
# print(s[1])
# print(s[2])
# # 0, 200
# s[0] = 200
# print(s[0])
# print(s.scores)
# del s[0]
# print(s.scores)
#**************************key獲取value值***********************
# 可以獲取所有的屬性為key值, 以及對應的value值, 並封裝為一個字典返回.
print(s.__dict__)
# str, list
# li = [1,2,3,4,5,6]
# __getitem__: li[0] === __getslice__
# __setitem__: li[0] = 10 == __setslice__
# __delitem__: del li[0] == __delslice__
class Student(object):
def __init__(self, name, scores):
self.name = name
self.scores = scores
# 支援索引; s[key]
def __getitem__(self, key):
# print("獲取索引對應的value值")
return self.__dict__[key]
# s[key] = 修改的值
def __setitem__(self, key, value):
self.__dict__[key] = value
# del s[key]
def __delitem__(self, key):
del self.__dict__[key]
def hello(self):
return "hello"
s = Student('westos', [101, 100, 100])
#**************************key獲取value值***********************
# 可以獲取所有的屬性為key值, 以及對應的value值, 並封裝為一個字典返回.
# print(s.__dict__)
print(s['name'])
print(s['scores'])
s['name'] = 'westo1'
print(s['name'])
del s['name']
print(s['name'])
# str, list
# li = [1,2,3,4,5,6]
# __getitem__: li[0] === __getslice__
# __setitem__: li[0] = 10 == __setslice__
# __delitem__: del li[0] == __delslice__
class Student(object):
def __init__(self, name, scores):
self.name = name
self.scores = scores
def __getitem__(self, key):
return self.scores[key]
def __setitem__(self, key, value):
self.scores[key] = value
def __delitem__(self, key):
del self.scores[key]
# 對於切片的操作*******
s = Student('westos', [101, 90, 101])
print(s[1:3])
s[1:3] = [0,0]
print(s[:])
del s[:-1]
print(s[:])
print(s[0])
8.重複與連線與成員操作符的實現
from collections import Iterable
class Student(object):
def __init__(self, name, scores):
self.name = name
self.scores = scores
self.power = 100
# obj1 + obj2
def __add__(self, other):
# 更新self物件的power屬性值;
self.power = self.power + other.power
return self
# obj1 * 3
def __mul__(self, other):
# *的效果是, 能量*power
return self.power * other
# 成員操作符; item in obj1
def __contains__(self, item):
return item in self.scores
# 可以for迴圈迭代
def __iter__(self):
"""
iter([1,2,3,4,5])
<list_iterator object at 0x7f6e1f51ffd0>
iter({1,2,3,4,5})
<set_iterator object at 0x7f6e1f567318>
"""
# 迭代返回的是成績
return iter(self.scores)
def __repr__(self):
return "Student:%s,%s" %(self.name, self.power)
# print("hello " + "world")
# print([1,2,3] + [3,4,5])
s1 = Student('westos1', [101,100,100])
s2 = Student('westos2', [100,100,100])
s3 = Student('westos3', [100,100,100])
# 連線的實現;
# "hello" + "world" + "hwllo"
print(s1 + s2 + s3)
# # a = 1 ; a+=1 a=2
# # str = "h"; str+='e' str=''he
# s1 += s2
# print(s1)
# 重複:
# a = 3; print(a*3)
# s = 'a'; print(s*3)
# li = [1,2,3]; print(li*3)
# print(s1*3)
# 成員操作符
# print(s1.scores)
# print(200 in s1)
# print(100 in s1)
# print(200 not in s1)
# print(100 not in s1)
# for迴圈迭代
# for i in s1:
# print(i)
# print(isinstance(s1, Iterable))
9.比較大小—計算長度
from django.core.paginator import Page
class Student(object):
def __init__(self, name, scores, power):
self.name = name
self.scores = scores
self.power = power
def __add__(self, other):
# 更新self物件的power屬性值;
self.power = self.power + other.power
return self
# obj1 > obj2
def __gt__(self, other):
return self.power > other.power
# obj >= obj2
__ge__ = lambda self, other: self.power >= other.power
# obj1 == obj2
def __eq__(self, other):
return self.power == other.power
def __ne__(self, other):
return self.power != other.power
# return not self.__eq__(other)
def __repr__(self):
return "Student:%s,%s" %(self.name, self.power)
def __len__(self):
return len(self.scores)
s1 = Student('westos1', [101,100,100], 100)
s2 = Student('westos2', [100,100,100], 101)
s3 = Student('westos3', [100,100,100], 80)
# print(s1+s2)
# print(s1 > s2 > s3)
# print(s1>=s2)
# print(s1<s2)
# print(s1 == s2)
# print(s1 != s2)
print(len(s1))
10.call方法
# 實現一個單例模式====
from django.core.paginator import Page
class Student(object):
def __init__(self, name, scores, power):
self.name = name
self.scores = scores
self.power = power
def __call__(self, *args, **kwargs):
return "物件被呼叫......"
# class: 例項化物件之前執行
def __new__(cls, *args, **kwargs):
# 判斷是否obj物件是否已經被建立, 如果沒有被建立, 則建立,
if not hasattr(cls, 'obj'):
cls.obj = object.__new__(cls)
# 如果已經建立成功,則返回建立好的物件
return cls.obj
s1 = Student('westos1', [101,100,100], 100)
s2 = Student('westos1', [101,100,100], 100)
print(s1)
print(s2)
11.參考程式碼
class Paginator(object):
def __init__(self, object_list, per_page, orphans=0,
allow_empty_first_page=True):
self.object_list = object_list
self._check_object_list_is_ordered()
self.per_page = int(per_page)
self.orphans = int(orphans)
self.allow_empty_first_page = allow_empty_first_page
def validate_number(self, number):
"""
Validates the given 1-based page number.
"""
try:
number = int(number)
except (TypeError, ValueError):
raise PageNotAnInteger(_('That page number is not an integer'))
if number < 1:
raise EmptyPage(_('That page number is less than 1'))
if number > self.num_pages:
if number == 1 and self.allow_empty_first_page:
pass
else:
raise EmptyPage(_('That page contains no results'))
return number
def page(self, number):
"""
Returns a Page object for the given 1-based page number.
"""
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page
if top + self.orphans >= self.count:
top = self.count
return self._get_page(self.object_list[bottom:top], number, self)
def _get_page(self, *args, **kwargs):
"""
Returns an instance of a single page.
This hook can be used by subclasses to use an alternative to the
standard :cls:`Page` object.
"""
return Page(*args, **kwargs)
@cached_property
def count(self):
"""
Returns the total number of objects, across all pages.
"""
try:
return self.object_list.count()
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
return len(self.object_list)
@cached_property
def num_pages(self):
"""
Returns the total number of pages.
"""
if self.count == 0 and not self.allow_empty_first_page:
return 0
hits = max(1, self.count - self.orphans)
return int(ceil(hits / float(self.per_page)))
@property
def page_range(self):
"""
Returns a 1-based range of pages for iterating through within
a template for loop.
"""
return six.moves.range(1, self.num_pages + 1)
def _check_object_list_is_ordered(self):
"""
Warn if self.object_list is unordered (typically a QuerySet).
"""
if hasattr(self.object_list, 'ordered') and not self.object_list.ordered:
warnings.warn(
'Pagination may yield inconsistent results with an unordered '
'object_list: {!r}'.format(self.object_list),
UnorderedObjectListWarning
)
QuerySetPaginator = Paginator # For backwards-compatibility.
class Page(collections.Sequence):
def __init__(self, object_list, number, paginator):
self.object_list = object_list
self.number = number
self.paginator = paginator
def __repr__(self):
return '<Page %s of %s>' % (self.number, self.paginator.num_pages)
def __len__(self):
return len(self.object_list)
def __getitem__(self, index):
if not isinstance(index, (slice,) + six.integer_types):
raise TypeError
# The object_list is converted to a list so that if it was a QuerySet
# it won't be a database hit per __getitem__.
if not isinstance(self.object_list, list):
self.object_list = list(self.object_list)
return self.object_list[index]
def has_next(self):
return self.number < self.paginator.num_pages
def has_previous(self):
return self.number > 1
def has_other_pages(self):
return self.has_previous() or self.has_next()
def next_page_number(self):
return self.paginator.validate_number(self.number + 1)
def previous_page_number(self):
return self.paginator.validate_number(self.number - 1)
def start_index(self):
"""
Returns the 1-based index of the first object on this page,
relative to total objects in the paginator.
"""
# Special case, return zero if no items.
if self.paginator.count == 0:
return 0
return (self.paginator.per_page * (self.number - 1)) + 1
def end_index(self):
"""
Returns the 1-based index of the last object on this page,
relative to total objects found (hits).
"""
# Special case for the last page because there can be orphans.
if self.number == self.paginator.num_pages:
return self.paginator.count
return self.number * self.paginator.per_page