1.魔法函式
python中常見的內置型別

什么是魔法函式?
python的魔法函式總被雙下劃線包圍,它們可以給你的類增加特殊的方法,如果你的物件實作了這些方法中的一個,那么這個方法就會在特殊情況下被呼叫,你可以定義想要
的行為,而這一切都是自動發生的,
魔法函式一覽

魔法函式舉例
1.1.__getitem__
把物件變成可迭代的物件
例子:
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
#魔法函式,給類加可迭代型別
def __getitem__(self, item):
return self.employee[item]
company = Company(['11','22','33'])
#加了魔法函式“__getitem__”,類就成了可迭代的了
for em in company:
print(em) #11,22,33
如果不用魔法函式回圈出每個員工的方法
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
company = Company(['11','22','33'])
for em in company.employee:
print(em)
還可以切片和獲取長度
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
#魔法函式
def __getitem__(self, item):
return self.employee[item]
company = Company(['11','22','33'])
#可以切片
company1 = company[:2]
#可以判斷len長度
print(len(company1)) #2
for em in company1:
print(em) #11,22
1.2.__len__
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
#
# def __getitem__(self, item):
# return self.employee[item]
def __len__(self):
return len(self.employee)
company = Company(["11", "22", "33"])
#如果不加魔法函式,len(company)會報錯的
print(len(company)) #3
1.3. __repr__和__str__
1.安裝互動環境(jupyter)
pip install -i https://pypi.douban.com/simple ipython
pip install -i https://pypi.douban.com/simple notebook
#啟動
ipython notebook
2.__repr__和__str__的用法


2.深入類和物件
1.1.鴨子型別和多型
“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子,”
我們并不關心物件是什么型別,到底是不是鴨子,只關心行為,
實體一:
# 鴨子型別和多型簡單實體
class Dog(object):
def say(self):
print('a dog')
class Cat(object):
def say(self):
print('a cat')
class Duck(object):
def say(self):
print('a duck')
animal_list = [Dog,Cat,Duck]
for animal in animal_list:
animal().say()
#運行結果
a dog
a cat
a duck
實體二:
類只要實作了__getitem__方法,它就是可迭代的,并不關心物件的本身,只關心行為,然后就可以當做extend的引數,
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
company = Company(["11", "22", "33"])
a = ['derek1','derek2']
name_set = set()
name_set.add('tom1')
name_set.add(('tom2'))
#extend里面的引數介紹
#def extend(self, iterable): # real signature unknown; restored from __doc__
#""" L.extend(iterable) -> None -- extend list by appending elements from the iterable """
#extend里面可以添加任何可迭代的引數,給類添加一個魔法函式__getitem__,類就變成可迭代的,所以可以extend進去
a.extend(company)
print(a) #['derek1', 'derek2', '11', '22', '33']
a.extend(name_set)
print(a) #['derek1', 'derek2', '11', '22', '33', 'tom2', 'tom1']
1.2.抽象基類(abc模塊)
抽象基類的作用類似于JAVA中的介面,在介面中定義各種方法,然后繼承介面的各種類進行具體方法的實作,抽象基類就是定義各種方法而不做具體實作的類,任何繼承自抽象基類的類必須實作這些方法,否則無法實體化
(1)判斷類時候有某種屬性
#判斷類是否有某種屬性
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __len__(self):
return len(self.employee)
com = Company(["11", "22", "33"])
#hasattr判斷類有沒有某種屬性,方法也是類的屬性
print(hasattr(com,"__len__")) #True
#雖然用hasattr可以判斷,但正確的方式是定義一個抽象基類
#我們在某些情況下希望判定某個物件的型別,可以用抽象基類
from collections.abc import Sized
print(isinstance(com,Sized)) #True
# print(len(com))
class Sized(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __len__(self):
return 0
@classmethod
def __subclasshook__(cls, C):
if cls is Sized:
return _check_methods(C, "__len__")
return NotImplemented
(2)abc模塊
簡單抽象基類實體
#模擬一個抽象基類
#寫一個抽象基類,它的子類必須要重寫抽象基類里面的方法
import abc
#定義一個抽象基類
class CacheBase(metaclass=abc.ABCMeta):
@abc.abstractclassmethod
def get(self,key):
pass
@abc.abstractclassmethod
def set(self,key,value):
pass
#子類,必須有抽象基類里面的方法,get和set
#假入不寫set方法會報錯
class RedisCache(CacheBase):
def get(self,key):
pass
# def set(self,key,value):
# pass
redis_cache = RedisCache()
#模擬一個抽象基類
#寫一個抽象基類,它的子類必須要重寫抽象基類里面的方法
import abc
#定義一個抽象基類
class CacheBase(metaclass=abc.ABCMeta):
@abc.abstractclassmethod
def get(self,key):
pass
@abc.abstractclassmethod
def set(self,key,value):
pass
#子類,必須有抽象基類里面的方法,get和set
#假入不寫set方法會報錯
class RedisCache(CacheBase):
def get(self,key):
pass
def set(self,key,value):
pass
redis_cache = RedisCache()

(3)abc里面所有的抽象基類
from collections.abc import *
所有的抽象基類
# Copyright 2007 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.
"""Abstract Base Classes (ABCs) for collections, according to PEP 3119.
Unit tests are in test_collections.
"""
from abc import ABCMeta, abstractmethod
import sys
__all__ = ["Awaitable", "Coroutine",
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
"Hashable", "Iterable", "Iterator", "Generator", "Reversible",
"Sized", "Container", "Callable", "Collection",
"Set", "MutableSet",
"Mapping", "MutableMapping",
"MappingView", "KeysView", "ItemsView", "ValuesView",
"Sequence", "MutableSequence",
"ByteString",
]
# This module has been renamed from collections.abc to _collections_abc to
# speed up interpreter startup. Some of the types such as MutableMapping are
# required early but collections module imports a lot of other modules.
# See issue #19218
__name__ = "collections.abc"
# Private list of types that we want to register with the various ABCs
# so that they will pass tests like:
# it = iter(somebytearray)
# assert isinstance(it, Iterable)
# Note: in other implementations, these types might not be distinct
# and they may have their own implementation specific types that
# are not included on this list.
bytes_iterator = type(iter(b''))
bytearray_iterator = type(iter(bytearray()))
#callable_iterator = ???
dict_keyiterator = type(iter({}.keys()))
dict_valueiterator = type(iter({}.values()))
dict_itemiterator = type(iter({}.items()))
list_iterator = type(iter([]))
list_reverseiterator = type(iter(reversed([])))
range_iterator = type(iter(range(0)))
longrange_iterator = type(iter(range(1 << 1000)))
set_iterator = type(iter(set()))
str_iterator = type(iter(""))
tuple_iterator = type(iter(()))
zip_iterator = type(iter(zip()))
## views ##
dict_keys = type({}.keys())
dict_values = type({}.values())
dict_items = type({}.items())
## misc ##
mappingproxy = type(type.__dict__)
generator = type((lambda: (yield))())
## coroutine ##
async def _coro(): pass
_coro = _coro()
coroutine = type(_coro)
_coro.close() # Prevent ResourceWarning
del _coro
## asynchronous generator ##
async def _ag(): yield
_ag = _ag()
async_generator = type(_ag)
del _ag
### ONE-TRICK PONIES ###
def _check_methods(C, *methods):
mro = C.__mro__
for method in methods:
for B in mro:
if method in B.__dict__:
if B.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True
class Hashable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __hash__(self):
return 0
@classmethod
def __subclasshook__(cls, C):
if cls is Hashable:
return _check_methods(C, "__hash__")
return NotImplemented
class Awaitable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __await__(self):
yield
@classmethod
def __subclasshook__(cls, C):
if cls is Awaitable:
return _check_methods(C, "__await__")
return NotImplemented
class Coroutine(Awaitable):
__slots__ = ()
@abstractmethod
def send(self, value):
"""Send a value into the coroutine.
Return next yielded value or raise StopIteration.
"""
raise StopIteration
@abstractmethod
def throw(self, typ, val=None, tb=None):
"""Raise an exception in the coroutine.
Return next yielded value or raise StopIteration.
"""
if val is None:
if tb is None:
raise typ
val = typ()
if tb is not None:
val = val.with_traceback(tb)
raise val
def close(self):
"""Raise GeneratorExit inside coroutine.
"""
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError("coroutine ignored GeneratorExit")
@classmethod
def __subclasshook__(cls, C):
if cls is Coroutine:
return _check_methods(C, '__await__', 'send', 'throw', 'close')
return NotImplemented
Coroutine.register(coroutine)
class AsyncIterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __aiter__(self):
return AsyncIterator()
@classmethod
def __subclasshook__(cls, C):
if cls is AsyncIterable:
return _check_methods(C, "__aiter__")
return NotImplemented
class AsyncIterator(AsyncIterable):
__slots__ = ()
@abstractmethod
async def __anext__(self):
"""Return the next item or raise StopAsyncIteration when exhausted."""
raise StopAsyncIteration
def __aiter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is AsyncIterator:
return _check_methods(C, "__anext__", "__aiter__")
return NotImplemented
class AsyncGenerator(AsyncIterator):
__slots__ = ()
async def __anext__(self):
"""Return the next item from the asynchronous generator.
When exhausted, raise StopAsyncIteration.
"""
return await self.asend(None)
@abstractmethod
async def asend(self, value):
"""Send a value into the asynchronous generator.
Return next yielded value or raise StopAsyncIteration.
"""
raise StopAsyncIteration
@abstractmethod
async def athrow(self, typ, val=None, tb=None):
"""Raise an exception in the asynchronous generator.
Return next yielded value or raise StopAsyncIteration.
"""
if val is None:
if tb is None:
raise typ
val = typ()
if tb is not None:
val = val.with_traceback(tb)
raise val
async def aclose(self):
"""Raise GeneratorExit inside coroutine.
"""
try:
await self.athrow(GeneratorExit)
except (GeneratorExit, StopAsyncIteration):
pass
else:
raise RuntimeError("asynchronous generator ignored GeneratorExit")
@classmethod
def __subclasshook__(cls, C):
if cls is AsyncGenerator:
return _check_methods(C, '__aiter__', '__anext__',
'asend', 'athrow', 'aclose')
return NotImplemented
AsyncGenerator.register(async_generator)
class Iterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
return _check_methods(C, "__iter__")
return NotImplemented
class Iterator(Iterable):
__slots__ = ()
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
return _check_methods(C, '__iter__', '__next__')
return NotImplemented
Iterator.register(bytes_iterator)
Iterator.register(bytearray_iterator)
#Iterator.register(callable_iterator)
Iterator.register(dict_keyiterator)
Iterator.register(dict_valueiterator)
Iterator.register(dict_itemiterator)
Iterator.register(list_iterator)
Iterator.register(list_reverseiterator)
Iterator.register(range_iterator)
Iterator.register(longrange_iterator)
Iterator.register(set_iterator)
Iterator.register(str_iterator)
Iterator.register(tuple_iterator)
Iterator.register(zip_iterator)
class Reversible(Iterable):
__slots__ = ()
@abstractmethod
def __reversed__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Reversible:
return _check_methods(C, "__reversed__", "__iter__")
return NotImplemented
class Generator(Iterator):
__slots__ = ()
def __next__(self):
"""Return the next item from the generator.
When exhausted, raise StopIteration.
"""
return self.send(None)
@abstractmethod
def send(self, value):
"""Send a value into the generator.
Return next yielded value or raise StopIteration.
"""
raise StopIteration
@abstractmethod
def throw(self, typ, val=None, tb=None):
"""Raise an exception in the generator.
Return next yielded value or raise StopIteration.
"""
if val is None:
if tb is None:
raise typ
val = typ()
if tb is not None:
val = val.with_traceback(tb)
raise val
def close(self):
"""Raise GeneratorExit inside generator.
"""
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError("generator ignored GeneratorExit")
@classmethod
def __subclasshook__(cls, C):
if cls is Generator:
return _check_methods(C, '__iter__', '__next__',
'send', 'throw', 'close')
return NotImplemented
Generator.register(generator)
class Sized(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __len__(self):
return 0
@classmethod
def __subclasshook__(cls, C):
if cls is Sized:
return _check_methods(C, "__len__")
return NotImplemented
class Container(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __contains__(self, x):
return False
@classmethod
def __subclasshook__(cls, C):
if cls is Container:
return _check_methods(C, "__contains__")
return NotImplemented
class Collection(Sized, Iterable, Container):
__slots__ = ()
@classmethod
def __subclasshook__(cls, C):
if cls is Collection:
return _check_methods(C, "__len__", "__iter__", "__contains__")
return NotImplemented
class Callable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __call__(self, *args, **kwds):
return False
@classmethod
def __subclasshook__(cls, C):
if cls is Callable:
return _check_methods(C, "__call__")
return NotImplemented
### SETS ###
class Set(Collection):
"""A set is a finite, iterable container.
This class provides concrete generic implementations of all
methods except for __contains__, __iter__ and __len__.
To override the comparisons (presumably for speed, as the
semantics are fixed), redefine __le__ and __ge__,
then the other operations will automatically follow suit.
"""
__slots__ = ()
def __le__(self, other):
if not isinstance(other, Set):
return NotImplemented
if len(self) > len(other):
return False
for elem in self:
if elem not in other:
return False
return True
def __lt__(self, other):
if not isinstance(other, Set):
return NotImplemented
return len(self) < len(other) and self.__le__(other)
def __gt__(self, other):
if not isinstance(other, Set):
return NotImplemented
return len(self) > len(other) and self.__ge__(other)
def __ge__(self, other):
if not isinstance(other, Set):
return NotImplemented
if len(self) < len(other):
return False
for elem in other:
if elem not in self:
return False
return True
def __eq__(self, other):
if not isinstance(other, Set):
return NotImplemented
return len(self) == len(other) and self.__le__(other)
@classmethod
def _from_iterable(cls, it):
'''Construct an instance of the class from any iterable input.
Must override this method if the class constructor signature
does not accept an iterable for an input.
'''
return cls(it)
def __and__(self, other):
if not isinstance(other, Iterable):
return NotImplemented
return self._from_iterable(value for value in other if value in self)
__rand__ = __and__
def isdisjoint(self, other):
'Return True if two sets have a null intersection.'
for value in other:
if value in self:
return False
return True
def __or__(self, other):
if not isinstance(other, Iterable):
return NotImplemented
chain = (e for s in (self, other) for e in s)
return self._from_iterable(chain)
__ror__ = __or__
def __sub__(self, other):
if not isinstance(other, Set):
if not isinstance(other, Iterable):
return NotImplemented
other = self._from_iterable(other)
return self._from_iterable(value for value in self
if value not in other)
def __rsub__(self, other):
if not isinstance(other, Set):
if not isinstance(other, Iterable):
return NotImplemented
other = self._from_iterable(other)
return self._from_iterable(value for value in other
if value not in self)
def __xor__(self, other):
if not isinstance(other, Set):
if not isinstance(other, Iterable):
return NotImplemented
other = self._from_iterable(other)
return (self - other) | (other - self)
__rxor__ = __xor__
def _hash(self):
"""Compute the hash value of a set.
Note that we don't define __hash__: not all sets are hashable.
But if you define a hashable set type, its __hash__ should
call this function.
This must be compatible __eq__.
All sets ought to compare equal if they contain the same
elements, regardless of how they are implemented, and
regardless of the order of the elements; so there's not much
freedom for __eq__ or __hash__. We match the algorithm used
by the built-in frozenset type.
"""
MAX = sys.maxsize
MASK = 2 * MAX + 1
n = len(self)
h = 1927868237 * (n + 1)
h &= MASK
for x in self:
hx = hash(x)
h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
h &= MASK
h = h * 69069 + 907133923
h &= MASK
if h > MAX:
h -= MASK + 1
if h == -1:
h = 590923713
return h
Set.register(frozenset)
class MutableSet(Set):
"""A mutable set is a finite, iterable container.
This class provides concrete generic implementations of all
methods except for __contains__, __iter__, __len__,
add(), and discard().
To override the comparisons (presumably for speed, as the
semantics are fixed), all you have to do is redefine __le__ and
then the other operations will automatically follow suit.
"""
__slots__ = ()
@abstractmethod
def add(self, value):
"""Add an element."""
raise NotImplementedError
@abstractmethod
def discard(self, value):
"""Remove an element. Do not raise an exception if absent."""
raise NotImplementedError
def remove(self, value):
"""Remove an element. If not a member, raise a KeyError."""
if value not in self:
raise KeyError(value)
self.discard(value)
def pop(self):
"""Return the popped value. Raise KeyError if empty."""
it = iter(self)
try:
value = https://www.cnblogs.com/geoffreygao/archive/2023/03/29/next(it)
except StopIteration:
raise KeyError
self.discard(value)
return value
def clear(self):"""This is slow (creates N new iterators!) but effective."""
try:
while True:
self.pop()
except KeyError:
pass
def __ior__(self, it):
for value in it:
self.add(value)
return self
def __iand__(self, it):
for value in (self - it):
self.discard(value)
return self
def __ixor__(self, it):
if it is self:
self.clear()
else:
if not isinstance(it, Set):
it = self._from_iterable(it)
for value in it:
if value in self:
self.discard(value)
else:
self.add(value)
return self
def __isub__(self, it):
if it is self:
self.clear()
else:
for value in it:
self.discard(value)
return self
MutableSet.register(set)
### MAPPINGS ###
class Mapping(Collection):
__slots__ = ()
"""A Mapping is a generic container for associating key/value
pairs.
This class provides concrete generic implementations of all
methods except for __getitem__, __iter__, and __len__.
"""
@abstractmethod
def __getitem__(self, key):
raise KeyError
def get(self, key, default=None):
'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.'
try:
return self[key]
except KeyError:
return default
def __contains__(self, key):
try:
self[key]
except KeyError:
return False
else:
return True
def keys(self):
"D.keys() -> a set-like object providing a view on D's keys"
return KeysView(self)
def items(self):
"D.items() -> a set-like object providing a view on D's items"
return ItemsView(self)
def values(self):
"D.values() -> an object providing a view on D's values"
return ValuesView(self)
def __eq__(self, other):
if not isinstance(other, Mapping):
return NotImplemented
return dict(self.items()) == dict(other.items())
__reversed__ = None
Mapping.register(mappingproxy)
class MappingView(Sized):
__slots__ = '_mapping',
def __init__(self, mapping):
self._mapping = mapping
def __len__(self):
return len(self._mapping)
def __repr__(self):
return '{0.__class__.__name__}({0._mapping!r})'.format(self)
class KeysView(MappingView, Set):
__slots__ = ()
@classmethod
def _from_iterable(self, it):
return set(it)
def __contains__(self, key):
return key in self._mapping
def __iter__(self):
yield from self._mapping
KeysView.register(dict_keys)
class ItemsView(MappingView, Set):
__slots__ = ()
@classmethod
def _from_iterable(self, it):
return set(it)
def __contains__(self, item):
key, value = https://www.cnblogs.com/geoffreygao/archive/2023/03/29/item
try:
v = self._mapping[key]
except KeyError:
return False
else:
return v is value or v == value
def __iter__(self):
for key in self._mapping:
yield (key, self._mapping[key])
ItemsView.register(dict_items)
class ValuesView(MappingView):
__slots__ = ()
def __contains__(self, value):
for key in self._mapping:
v = self._mapping[key]
if v is value or v == value:
return True
return False
def __iter__(self):
for key in self._mapping:
yield self._mapping[key]
ValuesView.register(dict_values)
class MutableMapping(Mapping):
__slots__ = ()"""A MutableMapping is a generic container for associating
key/value pairs.
This class provides concrete generic implementations of all
methods except for __getitem__, __setitem__, __delitem__,
__iter__, and __len__.
"""
@abstractmethod
def __setitem__(self, key, value):
raise KeyError
@abstractmethod
def __delitem__(self, key):
raise KeyError
__marker = object()
def pop(self, key, default=__marker):
'''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised.
'''
try:
value = https://www.cnblogs.com/geoffreygao/archive/2023/03/29/self[key]
except KeyError:
if default is self.__marker:
raise
return default
else:
del self[key]
return value
def popitem(self):'''D.popitem() -> (k, v), remove and return some (key, value) pair
as a 2-tuple; but raise KeyError if D is empty.
'''
try:
key = next(iter(self))
except StopIteration:
raise KeyError
value = https://www.cnblogs.com/geoffreygao/archive/2023/03/29/self[key]
del self[key]
return key, value
def clear(self):'D.clear() -> None. Remove all items from D.'
try:
while True:
self.popitem()
except KeyError:
pass
def update(*args, **kwds):
''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k, v in F.items(): D[k] = v
'''
if not args:
raise TypeError("descriptor 'update' of 'MutableMapping' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('update expected at most 1 arguments, got %d' %
len(args))
if args:
other = args[0]
if isinstance(other, Mapping):
for key in other:
self[key] = other[key]
elif hasattr(other, "keys"):
for key in other.keys():
self[key] = other[key]
else:
for key, value in other:
self[key] = value
for key, value in kwds.items():
self[key] = value
def setdefault(self, key, default=None):
'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D'
try:
return self[key]
except KeyError:
self[key] = default
return default
MutableMapping.register(dict)
### SEQUENCES ###
class Sequence(Reversible, Collection):
"""All the operations on a read-only sequence.
Concrete subclasses must override __new__ or __init__,
__getitem__, and __len__.
"""
__slots__ = ()
@abstractmethod
def __getitem__(self, index):
raise IndexError
def __iter__(self):
i = 0
try:
while True:
v = self[i]
yield v
i += 1
except IndexError:
return
def __contains__(self, value):
for v in self:
if v is value or v == value:
return True
return False
def __reversed__(self):
for i in reversed(range(len(self))):
yield self[i]
def index(self, value, start=0, stop=None):
'''S.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.
'''
if start is not None and start < 0:
start = max(len(self) + start, 0)
if stop is not None and stop < 0:
stop += len(self)
i = start
while stop is None or i < stop:
try:
v = self[i]
if v is value or v == value:
return i
except IndexError:
break
i += 1
raise ValueError
def count(self, value):
'S.count(value) -> integer -- return number of occurrences of value'
return sum(1 for v in self if v is value or v == value)
Sequence.register(tuple)
Sequence.register(str)
Sequence.register(range)
Sequence.register(memoryview)
class ByteString(Sequence):
"""This unifies bytes and bytearray.
XXX Should add all their methods.
"""
__slots__ = ()
ByteString.register(bytes)
ByteString.register(bytearray)
class MutableSequence(Sequence):
__slots__ = ()
"""All the operations on a read-write sequence.
Concrete subclasses must provide __new__ or __init__,
__getitem__, __setitem__, __delitem__, __len__, and insert().
"""
@abstractmethod
def __setitem__(self, index, value):
raise IndexError
@abstractmethod
def __delitem__(self, index):
raise IndexError
@abstractmethod
def insert(self, index, value):
'S.insert(index, value) -- insert value before index'
raise IndexError
def append(self, value):
'S.append(value) -- append value to the end of the sequence'
self.insert(len(self), value)
def clear(self):
'S.clear() -> None -- remove all items from S'
try:
while True:
self.pop()
except IndexError:
pass
def reverse(self):
'S.reverse() -- reverse *IN PLACE*'
n = len(self)
for i in range(n//2):
self[i], self[n-i-1] = self[n-i-1], self[i]
def extend(self, values):
'S.extend(iterable) -- extend sequence by appending elements from the iterable'
for v in values:
self.append(v)
def pop(self, index=-1):
'''S.pop([index]) -> item -- remove and return item at index (default last).
Raise IndexError if list is empty or index is out of range.
'''
v = self[index]
del self[index]
return v
def remove(self, value):
'''S.remove(value) -- remove first occurrence of value.
Raise ValueError if the value is not present.
'''
del self[self.index(value)]
def __iadd__(self, values):
self.extend(values)
return self
MutableSequence.register(list)
MutableSequence.register(bytearray) # Multiply inheriting, see ByteString

1.3.使用isinstance而不是type
(1)語法
isinstance(object, classinfo)
其中,object 是變數,classinfo 是型別即 (tuple,dict,int,float,list,bool等) 和 class類
若引數 object 是 classinfo 類的實體,或者 object 是 classinfo 類的子類的一個實體, 回傳 True,
若 object 不是一個給定型別的的物件, 則回傳結果總是False,
若 classinfo 不是一種資料型別或者由資料型別構成的元組,將引發一個 TypeError 例外,
(2)isinstance簡單用法
>>> isinstance(1,int)
True
>>>
>>> isinstance('1',str)
True
>>>
>>> isinstance(1,list)
False
(3)type()與isinstance()的區別:
- 共同點:兩者都可以判斷物件型別
- 不同點:對于一個 class 類的子類物件型別判斷,type就不行了,而 isinstance 可以,
class A:
pass
class B(A):
pass
b = B()
#判斷b是不是B的型別
print(isinstance(b,B)) #True
# b是不是A的型別呢,也是的
#因為B繼承A,isinstance內部會去檢查繼承鏈
print(isinstance(b,A)) #True
print(type(b) is B) #True
#b指向了B()物件,雖然A是B的父類,但是A是另外一個物件,它們的id是不相等的
print(type(b) is A) #False
1.4.類變數和實體變數
python的類變數和實體變數,顧名思義,類變數是指跟類的變數,而實體變數,指跟類的具體實體相關聯的變數
class A:
#類變數
bb = 11
def __init__(self,x,y):
#實體變數
self.x = x
self.y = y
a = A(2,3)
A.bb = 111111
print(a.x,a.y,a.bb) # 2 3 111111
print(A.bb) # 111111
a.bb = 2222 #實際上會在實體物件a里面新建一個屬性bb
print(a.bb) # 2222
print(A.bb) # 111111
1.5.類和實體屬性的查找順序

class D:
pass
class C(D):
pass
class B(D):
pass
class A(B,C):
pass
#順序:A,B,C,D
#__mro__,類的屬性查找順序
print(A.__mro__) #(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)

class D:
pass
class E:
pass
class C(E):
pass
class B(D):
pass
class A(B,C):
pass
#順序:A,B,D,C,E
#__mro__,類的屬性查找順序
print(A.__mro__)
#(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)
1.6.類方法,靜態方法,和實體方法
實體:
class Date():
#建構式
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
#實體方法
def tomorrow(self):
self.day += 1
# 靜態方法不用寫self
@staticmethod
def parse_from_string(date_str):
year, month, day = tuple(date_str.split("-"))
# 靜態方法不好的地方是采用硬編碼,如果用類方法的話就不會了
return Date(int(year), int(month), int(day))
#類方法
@classmethod
def from_string(cls, date_str):
year, month, day = tuple(date_str.split("-"))
# cls:傳進來的類,而不是像靜態方法把類寫死了
return cls(int(year), int(month), int(day))
def __str__(self):
return '%s/%s/%s'%(self.year,self.month,self.day)
if __name__ == "__main__":
new_day = Date(2018,5,9)
#實體方法
new_day.tomorrow()
print(new_day) #2018/5/10
#靜態方法
date_str = '2018-05-09'
new_day = Date.parse_from_string(date_str)
print(new_day) #2018/5/9
# 類方法
date_str = '2018-05-09'
new_day = Date.from_string(date_str)
print(new_day) # 2018/5/9
1.7.python物件的自省機制
在計算機編程中,自省是指一種能力:檢查某些事物以確定它是什么、它知道什么以及它能做什么,自省向程式員提供了極大的靈活性和控制力,
class Person:
'''人類'''
name = "user"
class Student(Person):
def __init__(self,school_name):
self.school_name = school_name
if __name__ == "__main__":
user = Student('仙劍')
#通過 __dict__ 查詢有哪些屬性
print(user.__dict__) #{'school_name': '仙劍'}
print(Person.__dict__) #{'__module__': '__main__', '__doc__': '人類', 'name': 'user', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
print(Person.__doc__) #人類
#可以添加屬性
user.__dict__['school_addr'] = '北京'
print(user.school_addr) #北京
#dir也可以查看屬性,比__dict__功能更強大
print(dir(user))
#['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'school_addr', 'school_name']
1.8.super函式
super執行的順序
class A:
def __init__(self):
print('A')
class B(A):
def __init__(self):
print('B')
super().__init__()
class C(A):
def __init__(self):
print('C')
super().__init__()
class D(B,C):
def __init__(self):
print('D')
super(D, self).__init__()
if __name__ == '__main__':
print(D.__mro__) #(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d = D()
#執行結果
D
B
C
A
1.9.with陳述句(背景關系管理器)
#背景關系管理器
class Sample:
def __enter__(self):
print('enter')
#獲取資源
return self
def __exit__(self, exc_type, exc_val, exc_tb):
#釋放資源
print('exit')
def do_something(self):
print('doing something')
#會自動執行enter和exit方法
with Sample() as sample:
sample.do_something()
# 運行結果
enter
doing something
exit
3.python元類編程
1.1.propety動態屬性
在面向物件編程中,我們一般把名詞性的東西映射成屬性,動詞性的東西映射成方法,在python中他們對應的分別是屬性self.xxx和類方法,但有時我們需要的屬性需要根據其他屬性動態的計算,此時如果直接使用屬性方法處理,會導致資料不同步,下面介紹@property方法來動態創建類屬性,
from datetime import datetime,date
class User:
def __init__(self,name,birthday):
self.name = name
self.birthday = birthday
self._age = 0
@property
def age(self):
return datetime.now().year - self.birthday.year
@age.setter
def age(self,value):
self._age = value
if __name__ == '__main__':
user = User("derek",date(year=1994,month=11,day=11))
user.age = 23
print(user._age) # 23
print(user.age) # 24 ,動態計算出來的
1.2.__getattr__和__getattribute__的區別
object.__getattr__(self, name)
找不到attribute的時候,會呼叫getattr,回傳一個值或AttributeError例外,
object.__getattribute__(self, name)
無條件被呼叫,通過實體訪問屬性,如果class中定義了__getattr__(),則__getattr__()不會被呼叫(除非顯示呼叫或引發AttributeError例外)
(1)呼叫一個不存在的屬性
class User:
def __init__(self,info={}):
self.info = info
# def __getattr__(self, item):
# return self.info[item]
if __name__ == '__main__':
user = User(info={"name":"derek","age":24})
print(user.name)
會報錯

(2)加了__getattr__之后就可以呼叫了
class User:
def __init__(self,info={}):
self.info = info
#__getattr__是在查找不到屬性的時候呼叫
def __getattr__(self, item):
return self.info[item]
if __name__ == '__main__':
user = User(info={"name":"derek","age":24})
print(user.name) #derek
(3)__getattribute__
class User:
def __init__(self,info={}):
self.info = info
#__getattr__是在查找不到屬性的時候呼叫
def __getattr__(self, item):
return self.info[item]
#__getattribute不管屬性存不存在,都訪問這個
def __getattribute__(self, item):
return "zhang_derek"
if __name__ == '__main__':
user = User(info={"name":"derek","age":24})
#不管屬性存不存在,都走__getattribute__
print(user.name) #zhang_derek #即使屬性存在也走__getattribute__
print(user.test) #zhang_derek #不存在的屬性也能列印
print(user.company) #zhang_derek #不存在的屬性也能列印
1.3.屬性描述符
驗證賦值的時候是不是int型別
#屬性描述符
import numbers
#只要一個類實作了下面三種魔法函式中的一種,這個類就是屬性描述符
class IntField:
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if not isinstance(value,numbers.Integral):
raise ValueError("必須為int")
self.value = https://www.cnblogs.com/geoffreygao/archive/2023/03/29/value
def __delete__(self, instance):
pass
class User:
age = IntField()
if __name__ =='__main__':
user = User()
user.age = 24
print(user.age)
如果user.age=24,值是int,可以正常列印
如果user.age='test',傳一個字串,則會報錯

1.4.__new__和__init__的區別
(1)__new__方法如果不回傳物件,不會執行init方法
class User:
def __new__(cls, *args, **kwargs):
print("in new")
def __init__(self,name):
print("in init")
self.name = name
# new是用用來控制物件的生成程序,在物件生成之前
# init是用來完善物件的
# 如果new方法不回傳物件,則不會呼叫init函式
if __name__ == '__main__':
user = User("derek")
運行結果:沒有呼叫init方法

(2)回傳物件就會執行init方法
class User:
def __new__(cls, *args, **kwargs):
print("in new") #in new
print(cls) #cls是當前class物件 <class '__main__.User'>
print(type(cls)) #<class 'type'>
return super().__new__(cls) #必須回傳class物件,才會呼叫__init__方法
def __init__(self,name):
print("in init") #in init
print(self) #self是class的實體物件 <__main__.User object at 0x00000000021B8780>
print(type(self)) #<class '__main__.User'>
self.name = name
# new是用用來控制物件的生成程序,在物件生成之前
# init是用來完善物件的
# 如果new方法不回傳物件,則不會呼叫init函式
if __name__ == '__main__':
user = User(name="derek")
#總結
# __new__ 用來創建實體,在回傳的實體上執行__init__,如果不回傳實體那么__init__將不會執行
# __init__ 用來初始化實體,設定屬性什么的
1.5.自定義元類
(1)前戲:通過傳入不同的字串動態的創建不同的類
def create_class(name):
if name == 'user':
class User:
def __str__(self):
return "user"
return User
elif name == "company":
class Company:
def __str__(self):
return "company"
return Company
if __name__ == '__main__':
Myclass = create_class("user")
my_obj = Myclass()
print(my_obj) #user
print(type(my_obj)) #<class '__main__.create_class.<locals>.User'>
(2)用type創建
雖然上面的方法能夠創建,但很麻煩,下面是type創建類的一個簡單實體
# 一個簡單type創建類的例子
#type(object_or_name, bases, dict)
#type里面有三個引數,第一個類名,第二個基類名,第三個是屬性
User = type("User",(),{"name":"derek"})
my_obj = User()
print(my_obj.name) #derek
(3)不但可以定義屬性,還可以定義方法
def say(self): #必須加self
return "i am derek"
User = type("User",(),{"name":"derek","say":say})
my_obj = User()
print(my_obj.name) #derek
print(my_obj.say()) #i am derek
(4)讓type創建的類繼承一個基類
def say(self): #必須加self
return "i am derek"
class BaseClass:
def answer(self):
return "i am baseclass"
#type里面有三個引數,第一個類名,第二個基類名,第三個是屬性
User = type("User",(BaseClass,),{"name":"derek","say":say})
if __name__ == '__main__':
my_obj = User()
print(my_obj.name) # derek
print(my_obj.say()) # i am derek
print(my_obj.answer()) # i am baseclass
1.6.什么是元類?
元類就是創建類的類,比如上面的type
在實際編碼中,我們一般不直接用type去創建類,而是用元類的寫法,自定義一個元類metaclass去創建
# 把User類創建的程序委托給元類去做,這樣代碼的分離性比較好
class MetaClass(type):
def __new__(cls, *args, **kwargs):
return super().__new__(cls,*args, **kwargs)
class User(metaclass=MetaClass):
def __init__(self,name):
self.name = name
def __str__(self):
return "test"
if __name__ == '__main__':
#python中類的實體化程序,會首先尋找metaclass,通過metaclass去創建User類
my_obj = User(name="derek")
print(my_obj) #test
4.自定義序列類
1.1.序列型別的分類

1.2.序列的+和+=,extend和append的區別
from collections import abc
a = [1,2,]
c = a + [3,4]
print(c) #[1, 2, 3, 4]
#如果 + 元祖則會報錯, not tuple
# c = a + (3,4) #TypeError: can only concatenate list (not "tuple") to list
# + 是新生產一個list, += 是就地加,不會新生成list
#用+= 則可以是元祖,后面只要是可迭代的就行
#其原理是python內部抽象基類MutableSequence里面有個魔法函式__iadd__來實作的
a += (3,4) #[1, 2, 3, 4]
print(a)
a.extend((5,6))
print(a) #[1, 2, 3, 4, 5, 6]
a.append((7,8))
print(a) #[1, 2, 3, 4, 5, 6, (7, 8)]
#可以看到extend和append結果并不一樣,append是把里面當一個值傳進去,extend是迭代的傳進去
1.3.實作可切片的物件
(1)切片的用法
#模式[start:end:step]
"""
其中,第一個數字start表示切片開始位置,默認為0;
第二個數字end表示切片截止(但不包含)位置(默認為串列長度);
第三個數字step表示切片的步長(默認為1),
當start為0時可以省略,當end為串列長度時可以省略,
當step為1時可以省略,并且省略步長時可以同時省略最后一個冒號,
另外,當step為負整數時,表示反向切片,這時start應該比end的值要大才行,
"""
aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
#切片回傳的是一個新元素,不會改變原有的list
print (aList[::]) # 回傳包含原串列中所有元素的新串列 [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
print (aList[::-1]) # 回傳包含原串列中所有元素的逆序串列 [17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
print (aList[::2]) # 隔一個取一個,獲取偶數位置的元素 [3, 5, 7, 11, 15]
print (aList[1::2]) # 隔一個取一個,獲取奇數位置的元素 [4, 6, 9, 13, 17]
print (aList[3:6]) # 指定切片的開始和結束位置 [6, 7, 9]
print(aList[0:100]) # 切片結束位置大于串列長度時,從串列尾部截斷 [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
print(aList[100:]) # 切片開始位置大于串列長度時,回傳空串列 []
# aList[len(aList):] = [9] # 在串列尾部增加元素
# aList[:0] = [1, 2] # 在串列頭部插入元素
# aList[3:3] = [4] # 在串列中間位置插入元素
# aList[:3] = [1, 2] # 替換串列元素,等號兩邊的串列長度相等
# aList[3:] = [4, 5, 6] # 等號兩邊的串列長度也可以不相等
# aList[::2] = [0] * 3 # 隔一個修改一個
# print (aList)
# aList[::2] = ['a', 'b', 'c'] # 隔一個修改一個
# aList[::2] = [1,2] # 左側切片不連續,等號兩邊串列長度必須相等 #會報錯
# aList[:3] = [] # 洗掉串列中前3個元素
#洗掉
# del aList[:3] # 切片元素連續
# del aList[::2] # 切片元素不連續,隔一個刪一個
(2)實作物件支持切片操作
from collections import abc
#Sequence協議
import numbers
class Group:
#支持切片操作
def __init__(self, group_name, company_name, staffs):
self.group_name = group_name
self.company_name = company_name
self.staffs = staffs
def __reversed__(self):
self.staffs.reverse()
def __getitem__(self, item):
#當前的類
cls = type(self)
#判斷類是不是可切片的物件
if isinstance(item, slice):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=self.staffs[item])
elif isinstance(item, numbers.Integral):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs[item]])
def __len__(self):
return len(self.staffs)
def __iter__(self):
return iter(self.staffs)
def __contains__(self, item):
if item in self.staffs:
return True
else:
return False
staffs = ["derek1", "derek2", "derek3", "derek4"]
group = Group(company_name="alibaba", group_name="user", staffs=staffs)
#現在物件就成可切片的物件了
#__getitem__
for user in group:
print(user)
#運行結果
# derek1
# derek2
# derek3
# derek4
#__contains__
if 'derek1' in group:
print('yes')
1.4.串列生成式,字典推導式
# odd_list = []
# for i in range(21):
# if i%2 == 1:
# odd_list.append(i)
# print(odd_list) #[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
#串列生成式
#1.取出1-20之間的基數
odd_list = [i for i in range(21) if i %2 == 1]
print(odd_list) #[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
#2.取出1-20之間的基數的平方
def hadle_item(item):
return item * item
odd_list = [hadle_item(i) for i in range(21) if i %2 == 1]
print(odd_list) #[1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
利用字典推導式把字典的key和value做轉換:{key:value}變成{value:key}的形式
# 字典推導式的用法
my_dict = {'derek1':11,'derek2':22,'derek3':33}
reversed_dict = {value:key for key,value in my_dict.items()}
print(reversed_dict) #{11: 'derek1', 22: 'derek2', 33: 'derek3'}
https://www.cnblogs.com/derek1184405959/p/8579428.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548597.html
標籤:其他
上一篇:【Visual Leak Detector】配置項 TraceInternalFrames
下一篇:限流的幾種方案
