一、构造方法
构造方法用于初始化对象,当类被实例化时,首先就会调用构造方法,构造方法是特殊的方法,所以需要方法名需要在两侧加上"__",完整的构造方法应该是__init__。
class Fruits: def __init__(self): print("构造方法开始执行") def color(self): pass apple=Fruits()#构造方法开始执行 apple.color()
当创建类实例时,构造方法开始执行。
二、重写普通方法与构造方法
在类的继承中,一个类继承另一个类,会继承它所有的成员,但是,自己这个类也可以添加新的属性(不会影响到父类),一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准。
class A: def __init__(self): print("A中的构造方法") def method(self): print("A中的method方法") class B(A): def __init__(self): print("B中的构造方法") def method(self): print("B中的method方法") b=B() b.method() ########################输出########### #B中的构造方法 #B中的method方法
在python语言中,重写方法只看方法名,并不看参数,只要方法名相同,就会覆盖父类的同名方法。
三、super函数
通常需要在子类方法中调用超类的同名方法,因为同名方法会被子类方法覆盖,比如需要获取超类中同名方法的一个变量,就可以使用super函数。super函数的返回对象都是超类对象,所以访问super函数返回的对象中的资源都属于超类,super函数可以带两个参数,第一个表示当前的类型,第二个表示需要传入self,也可以不带参数。
class A: def __init__(self): self.name="bright" print("A中的构造方法") def method(self): print("A中的method方法") class B(A): def __init__(self): ########获取父类A中的name属性### super().__init__()#也可以这样写super(B,self).__init__() print("B中的构造方法") def method(self): print("B中的method方法") b=B() b.method() print(b.name)
可以看出,子类与父类方法名相同的情况下,会使用子类的方法,但是如果需要获取父类的相关属性,可以使用super函数获取,这里通过super函数获取父类的name属性值。
四、特殊成员方法
(一)自定义序列
有4个方法可以自定义自己的序列类,当对序列执行某些行为时,会触发该方法,它们是特殊方法,自然是名称前后都需要加上"__"
1、__len__(self)
返回序列中元素的个数,当使用len函数时会调用该方法
2、__getitem__(self,key)
返回键所对应的值。当使用sequence[key]获取值时会调用该方法
3、__setitem__(self,key,value)
设置key对应的值,当使用sequence[key]=value设置序列中键对应的值时调用该方法
4、__delitem__(self,key)
从序列中删除键为key的key-value对,当使用del关键字删除序列中键为key的key-value对时调用该方法
class FactoryDict: def __init__(self): self.dict={} def __getitem__(self, item): print("__getitem__方法被调用",item) return self.dict.get(item) def __setitem__(self, key, value): print("__setitem__方法被调用",key,value) self.dict[key]=value def __delitem__(self, key): print("__delitem__方法被调用",key) del self.dict[key] def __len__(self): return len(self.dict) f=FactoryDict() f["name"]="bright" f["age"]=27 print(f.dict) print(f["age"]) del f["name"] print(f.dict) print(len(f)) #######################输出############ #__setitem__方法被调用 name bright #__setitem__方法被调用 age 27 #{'name': 'bright', 'age': 27} #__getitem__方法被调用 age #27 #__delitem__方法被调用 name #{'age': 27} #1
(二)从内建列表、字符串、字典继承
在实现自定义的序列是,需要实现以上的4个方法,这样每次实现都需要写太过于麻烦,不过可以从python的内建类(list、dict、str)中继承,只需要实现自己的一些必需方法即可。
class list(object): """ list() -> new empty list list(iterable) -> new list initialized from iterable's items """ def append(self, p_object): # real signature unknown; restored from __doc__ """ L.append(object) -> None -- append object to end """ pass def clear(self): # real signature unknown; restored from __doc__ """ L.clear() -> None -- remove all items from L """ pass def copy(self): # real signature unknown; restored from __doc__ """ L.copy() -> list -- a shallow copy of L """ return [] def count(self, value): # real signature unknown; restored from __doc__ """ L.count(value) -> integer -- return number of occurrences of value """ return 0 def extend(self, iterable): # real signature unknown; restored from __doc__ """ L.extend(iterable) -> None -- extend list by appending elements from the iterable """ pass def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__ """ L.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. """ return 0 def insert(self, index, p_object): # real signature unknown; restored from __doc__ """ L.insert(index, object) -- insert object before index """ pass def pop(self, index=None): # real signature unknown; restored from __doc__ """ L.pop([index]) -> item -- remove and return item at index (default last). Raises IndexError if list is empty or index is out of range. """ pass def remove(self, value): # real signature unknown; restored from __doc__ """ L.remove(value) -> None -- remove first occurrence of value. Raises ValueError if the value is not present. """ pass def reverse(self): # real signature unknown; restored from __doc__ """ L.reverse() -- reverse *IN PLACE* """ pass def sort(self, key=None, reverse=False): # real signature unknown; restored from __doc__ """ L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE* """ pass def __add__(self, *args, **kwargs): # real signature unknown """ Return self+value. """ pass def __contains__(self, *args, **kwargs): # real signature unknown """ Return key in self. """ pass def __delitem__(self, *args, **kwargs): # real signature unknown """ Delete self[key]. """ pass def __eq__(self, *args, **kwargs): # real signature unknown """ Return self==value. """ pass def __getattribute__(self, *args, **kwargs): # real signature unknown """ Return getattr(self, name). """ pass def __getitem__(self, y): # real signature unknown; restored from __doc__ """ x.__getitem__(y) <==> x[y] """ pass def __ge__(self, *args, **kwargs): # real signature unknown """ Return self>=value. """ pass def __gt__(self, *args, **kwargs): # real signature unknown """ Return self>value. """ pass def __iadd__(self, *args, **kwargs): # real signature unknown """ Implement self+=value. """ pass def __imul__(self, *args, **kwargs): # real signature unknown """ Implement self*=value. """ pass def __init__(self, seq=()): # known special case of list.__init__ """ list() -> new empty list list(iterable) -> new list initialized from iterable's items # (copied from class doc) """ pass def __iter__(self, *args, **kwargs): # real signature unknown """ Implement iter(self). """ pass def __len__(self, *args, **kwargs): # real signature unknown """ Return len(self). """ pass def __le__(self, *args, **kwargs): # real signature unknown """ Return self<=value. """ pass def __lt__(self, *args, **kwargs): # real signature unknown """ Return self<value. """ pass def __mul__(self, *args, **kwargs): # real signature unknown """ Return self*value.n """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass def __ne__(self, *args, **kwargs): # real signature unknown """ Return self!=value. """ pass def __repr__(self, *args, **kwargs): # real signature unknown """ Return repr(self). """ pass def __reversed__(self): # real signature unknown; restored from __doc__ """ L.__reversed__() -- return a reverse iterator over the list """ pass def __rmul__(self, *args, **kwargs): # real signature unknown """ Return self*value. """ pass def __setitem__(self, *args, **kwargs): # real signature unknown """ Set self[key] to value. """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ L.__sizeof__() -- size of L in memory, in bytes """ pass __hash__ = None
class str(object): """ str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'. """ def capitalize(self): # real signature unknown; restored from __doc__ """ S.capitalize() -> str Return a capitalized version of S, i.e. make the first character have upper case and the rest lower case. """ return "" def casefold(self): # real signature unknown; restored from __doc__ """ S.casefold() -> str Return a version of S suitable for caseless comparisons. """ return "" def center(self, width, fillchar=None): # real signature unknown; restored from __doc__ """ S.center(width[, fillchar]) -> str Return S centered in a string of length width. Padding is done using the specified fill character (default is a space) """ return "" def count(self, sub, start=None, end=None): # real signature unknown; restored from __doc__ """ S.count(sub[, start[, end]]) -> int Return the number of non-overlapping occurrences of substring sub in string S[start:end]. Optional arguments start and end are interpreted as in slice notation. """ return 0 def encode(self, encoding='utf-8', errors='strict'): # real signature unknown; restored from __doc__ """ S.encode(encoding='utf-8', errors='strict') -> bytes Encode S using the codec registered for encoding. Default encoding is 'utf-8'. errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that can handle UnicodeEncodeErrors. """ return b"" def endswith(self, suffix, start=None, end=None): # real signature unknown; restored from __doc__ """ S.endswith(suffix[, start[, end]]) -> bool Return True if S ends with the specified suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. suffix can also be a tuple of strings to try. """ return False def expandtabs(self, tabsize=8): # real signature unknown; restored from __doc__ """ S.expandtabs(tabsize=8) -> str Return a copy of S where all tab characters are expanded using spaces. If tabsize is not given, a tab size of 8 characters is assumed. """ return "" def find(self, sub, start=None, end=None): # real signature unknown; restored from __doc__ """ S.find(sub[, start[, end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. """ return 0 def format(self, *args, **kwargs): # known special case of str.format """ S.format(*args, **kwargs) -> str Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}'). """ pass def format_map(self, mapping): # real signature unknown; restored from __doc__ """ S.format_map(mapping) -> str Return a formatted version of S, using substitutions from mapping. The substitutions are identified by braces ('{' and '}'). """ return "" def index(self, sub, start=None, end=None): # real signature unknown; restored from __doc__ """ S.index(sub[, start[, end]]) -> int Like S.find() but raise ValueError when the substring is not found. """ return 0 def isalnum(self): # real signature unknown; restored from __doc__ """ S.isalnum() -> bool Return True if all characters in S are alphanumeric and there is at least one character in S, False otherwise. """ return False def isalpha(self): # real signature unknown; restored from __doc__ """ S.isalpha() -> bool Return True if all characters in S are alphabetic and there is at least one character in S, False otherwise. """ return False def isdecimal(self): # real signature unknown; restored from __doc__ """ S.isdecimal() -> bool Return True if there are only decimal characters in S, False otherwise. """ return False def isdigit(self): # real signature unknown; restored from __doc__ """ S.isdigit() -> bool Return True if all characters in S are digits and there is at least one character in S, False otherwise. """ return False def isidentifier(self): # real signature unknown; restored from __doc__ """ S.isidentifier() -> bool Return True if S is a valid identifier according to the language definition. Use keyword.iskeyword() to test for reserved identifiers such as "def" and "class". """ return False def islower(self): # real signature unknown; restored from __doc__ """ S.islower() -> bool Return True if all cased characters in S are lowercase and there is at least one cased character in S, False otherwise. """ return False def isnumeric(self): # real signature unknown; restored from __doc__ """ S.isnumeric() -> bool Return True if there are only numeric characters in S, False otherwise. """ return False def isprintable(self): # real signature unknown; restored from __doc__ """ S.isprintable() -> bool Return True if all characters in S are considered printable in repr() or S is empty, False otherwise. """ return False def isspace(self): # real signature unknown; restored from __doc__ """ S.isspace() -> bool Return True if all characters in S are whitespace and there is at least one character in S, False otherwise. """ return False def istitle(self): # real signature unknown; restored from __doc__ """ S.istitle() -> bool Return True if S is a titlecased string and there is at least one character in S, i.e. upper- and titlecase characters may only follow uncased characters and lowercase characters only cased ones. Return False otherwise. """ return False def isupper(self): # real signature unknown; restored from __doc__ """ S.isupper() -> bool Return True if all cased characters in S are uppercase and there is at least one cased character in S, False otherwise. """ return False def join(self, iterable): # real signature unknown; restored from __doc__ """ S.join(iterable) -> str Return a string which is the concatenation of the strings in the iterable. The separator between elements is S. """ return "" def ljust(self, width, fillchar=None): # real signature unknown; restored from __doc__ """ S.ljust(width[, fillchar]) -> str Return S left-justified in a Unicode string of length width. Padding is done using the specified fill character (default is a space). """ return "" def lower(self): # real signature unknown; restored from __doc__ """ S.lower() -> str Return a copy of the string S converted to lowercase. """ return "" def lstrip(self, chars=None): # real signature unknown; restored from __doc__ """ S.lstrip([chars]) -> str Return a copy of the string S with leading whitespace removed. If chars is given and not None, remove characters in chars instead. """ return "" def maketrans(self, *args, **kwargs): # real signature unknown """ Return a translation table usable for str.translate(). If there is only one argument, it must be a dictionary mapping Unicode ordinals (integers) or characters to Unicode ordinals, strings or None. Character keys will be then converted to ordinals. If there are two arguments, they must be strings of equal length, and in the resulting dictionary, each character in x will be mapped to the character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result. """ pass def partition(self, sep): # real signature unknown; restored from __doc__ """ S.partition(sep) -> (head, sep, tail) Search for the separator sep in S, and return the part before it, the separator itself, and the part after it. If the separator is not found, return S and two empty strings. """ pass def replace(self, old, new, count=None): # real signature unknown; restored from __doc__ """ S.replace(old, new[, count]) -> str Return a copy of S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. """ return "" def rfind(self, sub, start=None, end=None): # real signature unknown; restored from __doc__ """ S.rfind(sub[, start[, end]]) -> int Return the highest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. """ return 0 def rindex(self, sub, start=None, end=None): # real signature unknown; restored from __doc__ """ S.rindex(sub[, start[, end]]) -> int Like S.rfind() but raise ValueError when the substring is not found. """ return 0 def rjust(self, width, fillchar=None): # real signature unknown; restored from __doc__ """ S.rjust(width[, fillchar]) -> str Return S right-justified in a string of length width. Padding is done using the specified fill character (default is a space). """ return "" def rpartition(self, sep): # real signature unknown; restored from __doc__ """ S.rpartition(sep) -> (head, sep, tail) Search for the separator sep in S, starting at the end of S, and return the part before it, the separator itself, and the part after it. If the separator is not found, return two empty strings and S. """ pass def rsplit(self, sep=None, maxsplit=-1): # real signature unknown; restored from __doc__ """ S.rsplit(sep=None, maxsplit=-1) -> list of strings Return a list of the words in S, using sep as the delimiter string, starting at the end of the string and working to the front. If maxsplit is given, at most maxsplit splits are done. If sep is not specified, any whitespace string is a separator. """ return [] def rstrip(self, chars=None): # real signature unknown; restored from __doc__ """ S.rstrip([chars]) -> str Return a copy of the string S with trailing whitespace removed. If chars is given and not None, remove characters in chars instead. """ return "" def split(self, sep=None, maxsplit=-1): # real signature unknown; restored from __doc__ """ S.split(sep=None, maxsplit=-1) -> list of strings Return a list of the words in S, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done. If sep is not specified or is None, any whitespace string is a separator and empty strings are removed from the result. """ return [] def splitlines(self, keepends=None): # real signature unknown; restored from __doc__ """ S.splitlines([keepends]) -> list of strings Return a list of the lines in S, breaking at line boundaries. Line breaks are not included in the resulting list unless keepends is given and true. """ return [] def startswith(self, prefix, start=None, end=None): # real signature unknown; restored from __doc__ """ S.startswith(prefix[, start[, end]]) -> bool Return True if S starts with the specified prefix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. prefix can also be a tuple of strings to try. """ return False def strip(self, chars=None): # real signature unknown; restored from __doc__ """ S.strip([chars]) -> str Return a copy of the string S with leading and trailing whitespace removed. If chars is given and not None, remove characters in chars instead. """ return "" def swapcase(self): # real signature unknown; restored from __doc__ """ S.swapcase() -> str Return a copy of S with uppercase characters converted to lowercase and vice versa. """ return "" def title(self): # real signature unknown; restored from __doc__ """ S.title() -> str Return a titlecased version of S, i.e. words start with title case characters, all remaining cased characters have lower case. """ return "" def translate(self, table): # real signature unknown; restored from __doc__ """ S.translate(table) -> str Return a copy of the string S in which each character has been mapped through the given translation table. The table must implement lookup/indexing via __getitem__, for instance a dictionary or list, mapping Unicode ordinals to Unicode ordinals, strings, or None. If this operation raises LookupError, the character is left untouched. Characters mapped to None are deleted. """ return "" def upper(self): # real signature unknown; restored from __doc__ """ S.upper() -> str Return a copy of S converted to uppercase. """ return "" def zfill(self, width): # real signature unknown; restored from __doc__ """ S.zfill(width) -> str Pad a numeric string S with zeros on the left, to fill a field of the specified width. The string S is never truncated. """ return "" def __add__(self, *args, **kwargs): # real signature unknown """ Return self+value. """ pass def __contains__(self, *args, **kwargs): # real signature unknown """ Return key in self. """ pass def __eq__(self, *args, **kwargs): # real signature unknown """ Return self==value. """ pass def __format__(self, format_spec): # real signature unknown; restored from __doc__ """ S.__format__(format_spec) -> str Return a formatted version of S as described by format_spec. """ return "" def __getattribute__(self, *args, **kwargs): # real signature unknown """ Return getattr(self, name). """ pass def __getitem__(self, *args, **kwargs): # real signature unknown """ Return self[key]. """ pass def __getnewargs__(self, *args, **kwargs): # real signature unknown pass def __ge__(self, *args, **kwargs): # real signature unknown """ Return self>=value. """ pass def __gt__(self, *args, **kwargs): # real signature unknown """ Return self>value. """ pass def __hash__(self, *args, **kwargs): # real signature unknown """ Return hash(self). """ pass def __init__(self, value='', encoding=None, errors='strict'): # known special case of str.__init__ """ str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'. # (copied from class doc) """ pass def __iter__(self, *args, **kwargs): # real signature unknown """ Implement iter(self). """ pass def __len__(self, *args, **kwargs): # real signature unknown """ Return len(self). """ pass def __le__(self, *args, **kwargs): # real signature unknown """ Return self<=value. """ pass def __lt__(self, *args, **kwargs): # real signature unknown """ Return self<value. """ pass def __mod__(self, *args, **kwargs): # real signature unknown """ Return self%value. """ pass def __mul__(self, *args, **kwargs): # real signature unknown """ Return self*value.n """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass def __ne__(self, *args, **kwargs): # real signature unknown """ Return self!=value. """ pass def __repr__(self, *args, **kwargs): # real signature unknown """ Return repr(self). """ pass def __rmod__(self, *args, **kwargs): # real signature unknown """ Return value%self. """ pass def __rmul__(self, *args, **kwargs): # real signature unknown """ Return self*value. """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ S.__sizeof__() -> size of S in memory, in bytes """ pass def __str__(self, *args, **kwargs): # real signature unknown """ Return str(self). """ pass
class dict(object): """ dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) """ def clear(self): # real signature unknown; restored from __doc__ """ D.clear() -> None. Remove all items from D. """ pass def copy(self): # real signature unknown; restored from __doc__ """ D.copy() -> a shallow copy of D """ pass @staticmethod # known case def fromkeys(*args, **kwargs): # real signature unknown """ Returns a new dict with keys from iterable and values equal to value. """ pass def get(self, k, d=None): # real signature unknown; restored from __doc__ """ D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. """ pass def items(self): # real signature unknown; restored from __doc__ """ D.items() -> a set-like object providing a view on D's items """ pass def keys(self): # real signature unknown; restored from __doc__ """ D.keys() -> a set-like object providing a view on D's keys """ pass def pop(self, k, d=None): # real signature unknown; restored from __doc__ """ 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 """ pass def popitem(self): # real signature unknown; restored from __doc__ """ D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty. """ pass def setdefault(self, k, d=None): # real signature unknown; restored from __doc__ """ D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D """ pass def update(self, E=None, **F): # known special case of dict.update """ D.update([E, ]**F) -> None. Update D from dict/iterable E and F. If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] """ pass def values(self): # real signature unknown; restored from __doc__ """ D.values() -> an object providing a view on D's values """ pass def __contains__(self, *args, **kwargs): # real signature unknown """ True if D has a key k, else False. """ pass def __delitem__(self, *args, **kwargs): # real signature unknown """ Delete self[key]. """ pass def __eq__(self, *args, **kwargs): # real signature unknown """ Return self==value. """ pass def __getattribute__(self, *args, **kwargs): # real signature unknown """ Return getattr(self, name). """ pass def __getitem__(self, y): # real signature unknown; restored from __doc__ """ x.__getitem__(y) <==> x[y] """ pass def __ge__(self, *args, **kwargs): # real signature unknown """ Return self>=value. """ pass def __gt__(self, *args, **kwargs): # real signature unknown """ Return self>value. """ pass def __init__(self, seq=None, **kwargs): # known special case of dict.__init__ """ dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) # (copied from class doc) """ pass def __iter__(self, *args, **kwargs): # real signature unknown """ Implement iter(self). """ pass def __len__(self, *args, **kwargs): # real signature unknown """ Return len(self). """ pass def __le__(self, *args, **kwargs): # real signature unknown """ Return self<=value. """ pass def __lt__(self, *args, **kwargs): # real signature unknown """ Return self<value. """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass def __ne__(self, *args, **kwargs): # real signature unknown """ Return self!=value. """ pass def __repr__(self, *args, **kwargs): # real signature unknown """ Return repr(self). """ pass def __setitem__(self, *args, **kwargs): # real signature unknown """ Set self[key] to value. """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ D.__sizeof__() -> size of D in memory, in bytes """ pass __hash__ = None
传入的列表每个值加上默认值
class MyList(list): def __init__(self,*args): #初始化列表 super(MyList,self).__init__(*args) #设置默认值 self.default_num=2 def __getitem__(self, item): return super().__getitem__(item)+self.default_num my_lsit=MyList([1,2,3]) print(my_lsit[2])#5
(三)属性
通常将类的成员变量称为属性。在创建实例后可以通过实例访问这些属性,但是却无法对属性进行二次操作,比如修改属性的值等。
1、传统属性
class Bar: def __init__(self): self.name="mget" #添加name属性值 b=Bar() b.name="mc" #修改name属性 print(b.name) #获取name属性
可以看到添加为类添加属性,需要在构造方法中通过self添加,读写属性需要创建实例,然后读写变量的值,但是这样是不能对name值进行过程监控的,所以可以加入两个方法进行属性值得读写。
class Bar: def __init__(self): self.name=None def setName(self,name): self.name=name def getName(self): return self.name b=Bar() b.name="gte"#改变name值 #通过setName设置属性值 b.setName("bright") #通过getName获取属性值 print(b.getName())
2、property函数
使用上述的setName,getName虽然可以解决属性监控的问题,但是也会暴露一些问题,这时可以使用property函数,在使用对象属性时,一般情况是直接使用obj.propertyName,同时也监控所有propertyName的读写操作。
property函数可以与三个函数进行绑定,该函数会创建一个属性,并通过返回值返回这个属性。property函数的第一个参数需要指定用于监控读属性值得方法,第二个参数用于监控写属性值的方法,第三个参数需要指定删除该属性时调用的方法。
class Bar: def __init__(self): self.name=None #用于写属性的操作,设置name def setName(self,name): self.name=name #用于读属性的才做,获取name def getName(self): return self.name def delName(self): self.name = None #通过property函数将上面3个方法与name属性绑定,对属性操作会调用相关的方法 propertyName=property(getName,setName,delName) b=Bar() #通过propertyName属性设置name的值,在设置属性值过程中setName方法被调用 b.propertyName="hti" #通过propertyName属性获取name的值,在获取属性值过程中getName方法被调用 print(b.propertyName) #通过propertyName属性删除name的值,在删除属性值过程中delName方法被调用 del b.propertyName print(b.propertyName)
使用property函数过程中注意:
- 用于监控属性读和删除操作的方法只能有一个参数self
- 用于监控属性写操作的方法除了self外,还需要有一个参数,用于接收设置属性的值
3、__setattr__、__getattr__、__delattr__
很明显上述针对的是一个属性的操作,如果需要需要对多个属性进行操作,那么又该如何做呢?
class Rectangle: def __init__(self): self.width=0 self.height=0 #设置size属性实际上设置了width、height的属性 def __setattr__(self, key, value): if key=="size": self.width,self.height=value else: self.__dict__[key]=value#用于保存成员变量的值 #获取size属性或者area属性实际上返回的是width,height,self.width*self.height def __getattr__(self, item): if item=="size": return self.width,self.height if item=="area": return self.width*self.height #删除size属性实际上将width,height的值设置为0 def __delattr__(self, item): if item=="size": self.width,self.height=0,0 r=Rectangle() r.size=10,20 print(r.size)#(10, 20) print(r.area)#200 print(r.__dict__)#{'height': 20, 'width': 10} del r.size print(r.size)#(0, 0)
上述的初始化了两个属性width、height,而size属性相当于这两个属性的组合,操作size也就相当于操作width、height这两个属性。
(四)静态方法和类方法
python类包含三种方法,实例方法、静态方法、类方法。这三类方法的特点:
- 实例方法必须是类实例后才能进行调用
- 静态方法不需要类的实例,不需要self参数
- 类方法调用方式与静态方法相同,定义方式与实例方法相同
定义静态方法需要使用@staticmethod装饰器,定义类方法需要使用@classmethod装饰器。
class Bar: def instanceMethod(self): #self表示当前对象 pass @staticmethod def staticMethod(): pass @classmethod def classMethod(cls): #表示类本身 pass
通过实例进行演示:
class Bar: name="bright" def __init__(self): # 定义实例变量,静态方法、类方法不能访问该变量 self.age = 27 #实例方法 def instanceMethod(self): #self表示当前对象 #访问类变量 print(self.name) #访问实例变量 print(self.age) #访问类方法 self.classMethod() # 访问静态方法 self.staticMethod() #静态方法 没有自动传值,就是一个普通工具 @staticmethod def staticMethod(): #访问类变量 print(Bar.name) print("我是静态方法") #类方法 类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入) @classmethod def classMethod(cls): #表示类本身 # 访问类变量 print(cls.name) print("我是类方法") #调用静态方法 Bar.staticMethod() #调用类方法 Bar.classMethod() #实例对象 b=Bar() #实例调用方法 b.instanceMethod() b.classMethod() b.staticMethod()
- 类中定义的静态变量(name)可以被实例方法、静态方法、类方法访问
- 实例中定义的实例变量(age)只能被实例方法访问
- 实例方法不能被静态方法、类方法访问,但静态方法、类方法可以被实例方法访问
五、描述符
(一)描述符简介
至少实现了__get__(),__set__(),__delete__()中的一个方法的新式类称之为描述符,描述符的作用是用来代理一个类的属性,需要注意的是描述符不能定义在类的构造函数中,只能定义为类的属性,它只属于类的,不属于实例。
- __get__():调用一个属性时,触发
- __set__():为一个属性赋值时,触发
- __delete__():del删除属性时,触发
class F00: def __get__(self, instance, owner): print("调用__get__方法") def __set__(self, instance, value): print("调用__set__方法") def __delete__(self, instance): print("调用__del__方法") #无法触发描述符 f=F00() f.name="bright"
如果像上述实例化描述符,并且进行属性操作,并不会触发描述符,只有定义成另外一个类的类属性,并且在对属性进行操作时才会触发。
class Fruits: def __init__(self,name,price): self.name=name self.price=price def __set__(self, instance, value): """ :param instance:描述符类的对象 :param value:是instance的值 :return: """ print("__set__") instance.__dict__[self.name] = value #为实例字典的key设值 def __get__(self, instance, owner): """ :param instance: :param owner: 是instance的类 :return: """ print("__get__") return instance.__dict__[self.name] #将参数存入实例的字典 def __delete__(self, instance): print("__delete__") instance.__dict__.pop(self.name) #删除实例字典的key class Apple: f=Fruits("apple",12) apple=Apple() apple.f="pear" #触发__set__ apple.f #触发__get__ del apple.f #触发__delete__
(二)描述符分类
- 数据描述符 至少实现了__get__()和__set__()
class F00: def __get__(self, instance, owner): print("调用__get__方法") def __set__(self, instance, value): print("调用__set__方法")
- 非数据描述符 没有实现__set__()
(三)优先级
1、类属性 > 数据描述符
class F00: def __get__(self, instance, owner): print("调用__get__方法") def __set__(self, instance, value): print("调用__set__方法") def __delete__(self, instance): print("调用__del__方法") class Bar: x=F00() Bar.x="hell"#没有执行描述符的set内置属性 print(Bar.x)#输出hell
使用Bar.x="hell"没有执行描述符的set内置属性,说明类属性覆盖了数据描述符,类属性的优先级大于数据描述符。
2、数据描述符 > 实例属性
class F00: def __get__(self, instance, owner): print("调用__get__方法") def __set__(self, instance, value): print("调用__set__方法") def __delete__(self, instance): print("调用__del__方法") class Bar: x=F00() def __init__(self,x): self.x=x b=Bar(2)#执行描述符的set内置属性 b.x #执行描述符的get内置属性 print(b.__dict__)#{} print(Bar.__dict__)#存在x且为数据描述符
实例属性x被数据描述符所覆盖,数据描述符的优先级大于实例属性的优先级。
(四)应用
1、类的装饰器
def Handle(cls): print('类的装饰器开始运行') return cls @Handle #Fruits=handle(Fruits) class Fruits: def __init__(self,name,price): self.name=name self.price=price
def City(*args,**kwargs): def Handle(cls): print('类的装饰器开始运行') return cls return Handle @City("西安") #@City("西安")---》@Handle----》Fruits=Handle(Fruits),参数已经传入 class Fruits: def __init__(self,name,price): self.name=name self.price=price
2、@classmethod的实现
class action_class_method: def __init__(self,func): self.func=func def __get__(self, instance, owner): """ :param instance: Animals的实例 :param owner: Animals :return: """ #对传入的函数进行操作,最后返回该函数 def wrapper(*args,**kwargs): return self.func(owner,*args,**kwargs) return wrapper class Animals: @action_class_method #eat=action_class_method(eat)相当于action_class_method作为一个描述符,调用eat()方法会触发__get__ def eat(cls): print("吃东西") def run(self): print("跑") Animals.eat()
3、@staticmethod的实现
staticmethod方法与classmethod方法的区别在于classmethod方法在使用时需要传入一个类的引用作为参数,而staticmethod则不用。
class action_static_method: def __init__(self,func): self.func=func def __get__(self, instance, owner): """ :param instance: Animals的实例 :param owner: Animals :return: """ #对传入的函数进行操作,最后返回该函数 def wrapper(*args,**kwargs): return self.func(*args,**kwargs) return wrapper class Animals: @action_static_method #eat=action_class_method(eat)相当于action_class_method作为一个描述符,调用eat()方法会触发__get__ def eat(*args): #无需传入self参数 print("吃东西",*args) def run(self): print("跑") Animals.eat("meet")
4、@property的实现
class CustomerlizeProperty: def __init__(self,func): self.func=func def __get__(self, instance, owner): #自己定制的静态属性,r.area实际是要执行r.area() if instance is None: return self return self.func(instance) #自动传递self class Rectangle: def __init__(self,a,b): self.a=a self.b=b @CustomerlizeProperty #area=CustomerlizeProperty(area) def area(self): return self.a*self.b r=Rectangle(2,4) print(r.area)
六、上下文管理协议
在进行文件操作时经常使用with语句,而这样的操作后面究竟做了什么呢?
class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') return self def __exit__(self, exc_type, exc_val, exc_tb): """ :param exc_type:异常类型 :param exc_val:异常值 :param exc_tb:追溯信息 :return: """ print('with中代码块执行完毕时执行') with Open("a.txt") as f: print(f,f.name) ###########输出########### #出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量 #<__main__.Open object at 0x0000000000697908> a.txt #with中代码块执行完毕时执行
class Open: def __init__(self,filepath,mode="r",encoding="utf-8"): self.filepath=filepath self.mode=mode self.encoding=encoding def __enter__(self): self.f=open(self.filepath,mode=self.mode,encoding=self.encoding) return self.f def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() return True #如果__exit()返回值为True,异常会被清空,with后的语句正常执行 with Open('B.txt','w') as f: f.write('ABCD')
七、__new__、__init__、__call__
类在进行实例化时,实际上是包含两个动作的:
- 创建对象
- 初始化对象
__new__方法就是用于创建一个对象,并且返回对象;__init__方法就是用于初始化对象,设置对象属性的一些初始值。也就是说,__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例属性设置一些参数。
class Animals: def __init__(self): print("执行init方法") def __call__(self, *args, **kwargs): print("执行call方法") def __new__(cls, *args, **kwargs): print(cls,"执行new方法") #cls指向的是Animals这个类 return object.__new__(cls) #如果这里没有返回值,init方法不会执行 def run(self): print("执行run方法") cat=Animals() cat() #执行call方法 ####输出#### #<class '__main__.Animals'> 执行new方法 #执行init方法 #执行call方法
__call__方法是对象后面加括号,触发执行。
需要注意的是:
- __new__至少要有一个参数cls,代表要实例化的类
- __new__必须要有返回值,返回实例化出来的实例,可以return父类__new__出来的实例,或者是object的__new__出来的实例
- __init__有一个参数self,就是这个__new__返回的实例
- __call__方法是对象后面加括号,触发执行
利用__new__进行单例模式
在django admin中使用了单例模式,可以使用__new__方法模拟一下,现在需要将所有注册的modelclass放入一个实例列表中,也就是说所有注册的模型都会出现在一个列表中。
class SingleTon(object): _instance = {} def __new__(cls, *args, **kwargs): if cls not in cls._instance: cls._instance[cls] = super(SingleTon, cls).__new__(cls, *args, **kwargs) print(cls._instance) return cls._instance[cls] class AdminSite(SingleTon): def __init__(self): self._registry=[] def register(self,modelclass): self._registry.append(modelclass)
###创建三个实例进行测试,结果将A、B类都注册到一个列表中,实例site3的列表非空 site1=AdminSite() site2=AdminSite() site3=AdminSite() class A: pass class B: pass site1.register(A) site2.register(B) print(site3._registry) ###############输出################## #{<class '__main__.AdminSite'>: <__main__.AdminSite object at 0x0000000000DF2470>} #{<class '__main__.AdminSite'>: <__main__.AdminSite object at 0x0000000000DF2470>} #{<class '__main__.AdminSite'>: <__main__.AdminSite object at 0x0000000000DF2470>} #[<class '__main__.A'>, <class '__main__.B'>]
八、__next__和__iter__实现迭代器协议
如果在一个类中定义__iter__方法,那么这个类的实例就是一个迭代器。__iter__方法需要返回一个迭代器,所以返回对象本身(即self)即可。当对象每迭代一次时,就会调用迭代器中的另一个特殊成员方法__next__,该方法返回当前迭代的结果。
class Fibonacci: def __init__(self): self.a=0 self.b=1 def __iter__(self): return self def __next__(self): result=self.a #计算下一个迭代的值 self.a,self.b=self.b,self.a+self.b return result fibs=Fibonacci() for i in fibs: print(i) #迭代的值超过300退出 if i > 300: break
迭代器有很多优点,但是它已经不具备某些功能了,如索引取值、分片操作等。所以在很多时候可以将迭代器转成列表进行操作。在转换为列表时,需要给迭代器元素限定范围,否则内存溢出。若想迭代器停止工作,只需抛出StopIteration异常即可。
class Fibonacci: def __init__(self): self.a=0 self.b=1 def __iter__(self): return self def __next__(self): result=self.a #计算下一个迭代的值 self.a,self.b=self.b,self.a+self.b if result>300: raise StopIteration return result fibs=Fibonacci() print(list(fibs))#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]