大蟒蛇python教程共享Python类的定义继承调用比较方法技巧

一、类的约束

# _开头: 私有变量;  # __开问: 私有变量,不能被继承;  # __xxx__: 能被访问,不能被继承;  class a:  def __init__(self):  self._internal = 0 # 私有变量不能被访问  self.public = 1 # 可被访问  def public_method(self):  pass  def _private_method(self): # 私有方法不能被访问  pass  class b:  def __init__(self):  self.__private = 0 # 这个属性会在内存中被重新命名为_b__private    def __private_method(self): # 不能被访问,不能被继承  pass  def __private_method__(self): # 能被访问,不能被继承  pass

二、类的定义

2.1、创建创建

class dog:  a = "0"; #相当于public static变量,全局的  """__init__是一个默认的方法,且self为默认的,用self修饰的属性为public类型的类变量"""  def __init__(self, name, age):  self.name = name  self.age = age  self.sex = "1";#设置属性默认值    def sit(self):  print(self.name + "is now sitting" + "and sex is " + self.sex + dog.a)    @classmethod  def user_name(cls, name): #注意这种注解的用法  return cls()    dog = dog("kk", 12);  dog.sit()

2.1.1、类的导入

在python中分为文件、模块、类,其中文件和模块可划等价;所以导入有几种方式,比如dog.py文件中定义了两个class,则在使用类中导入方法有以下几种:

  • from car import dog;#导入一个模块中的特定类,使用时则直接car();
  • import car;#导入一个模块中的所有类,使用时则需要car.car();
  • from car import *;#不推荐,容易引起命名冲突问题
from collections import ordereddict; #使用标准类库  t = ordereddict();

2.1.2、构造器

class date:  # primary constructor  def __init__(self, year, month, day):  self.year = year  self.month = month  self.day = day    # alternate constructor  @classmethod  def today(cls):  t = time.localtime() #它接收一个class作为第一个参数,它被用来创建并返回最终的实例, 这个cls==__init__  return cls(t.tm_year, t.tm_mon, t.tm_mday)    a = date(2020, 5, 10) # primary  b = date.today() # alternate

减少构造函数的参数个数:

class structure1:  # class variable that specifies expected fields  _field_list = []    def __init__(self, *args):  if len(args) != len(self._field_list):  raise typeerror(f'expected {len(self._field_list)} arguments')  # set the arguments  for name, value in zip(self._field_list, args):  setattr(self, name, value)    # example class definitions  class course(structure1):  # 这行只是为了一个准许入判断,没有太多实际意思,或是一个声明  _field_list = ['course_name', 'total_class', 'score']    c = course('python', 30, 0.3);

关键字参数

class structure2:  _field_list = []    def __init__(self, *args, **kwargs):  if len(args) > len(self._field_list):  raise typeerror(f'expected {len(self._field_list)} arguments')  # set all of the positional arguments  for name, value in zip(self._field_list, args):  setattr(self, name, value)    # set the remaining keyword arguments  #是通过pop这种方式来检查的,在长度范围内如果pop出错则抛异常  for name in self._field_list[len(args):]:  setattr(self, name, kwargs.pop(name))    # check for any remaining unknown arguments  if kwargs:  raise typeerror(f"invalid argument(s): {','.join(kwargs)}")    # example use  class course(structure2):  _field_list = ['course_name', 'total_class', 'score']    course_1 = course('python', 30, 0.3)  course_2 = course('python', 30, score=0.3)  course_3 = course('python', total_class=30, score=0.3)

扩展关键字参数:

class structure3:  # class variable that specifies expected fields  _field_list = []    def __init__(self, *args, **kwargs):  if len(args) != len(self._field_list):  raise typeerror(f'expected {len(self._field_list)} arguments')    # set the arguments  for name, value in zip(self._field_list, args):  setattr(self, name, value)    # set the additional arguments (if any)  extra_args = kwargs.keys() - self._field_list  for name in extra_args:  setattr(self, name, kwargs.pop(name))    if kwargs:  raise typeerror(f"duplicate values for {','.join(kwargs)}")    # example use  if __name__ == '__main__':  class course(structure3):  _field_list = ['course_name', 'total_class', 'score']    course_1 = course('python', 30, 0.3)  course_2 = course('python', 30, 0.3, date='8/5/2020')

2.1.3、类属性

要创建一个新的实例属性,可以通过描述器的形式来定义它的功能,一个描述器就是一个实现了3个核心属性访问操作的类,分别对应getsetdelete这三个特殊的方法。

# descriptor attribute for an integer type-checked attribute  class integer:  def __init__(self, name):  self.name = name  """下面三个方法只是一个更严格的定义,可以不需要,要使用上面的描述器,需要把描述器放入到一个class中,这样所有对描述器的访问都会被get/set/delete所捕获"""  def __get__(self, instance, cls):  if not instance:  return self  else:  return instance.__dict__[self.name]  def __set__(self, instance, value):  if not isinstance(value, int):  raise typeerror('expected an int object')  instance.__dict__[self.name] = value  def __delete__(self, instance):  del instance.__dict__[self.name]

示例1:

class point:  """实例变量,和下面的x,y不是一回事"""  x = integer('x')  y = integer('y')    def __init__(self, x, y):  self.x = x  self.y = y  print(point.x.name) # x  point = point(3, 5)  print(f'point x = {point.x}') #3  print(f'point y = {point.y}') #5  point.y = 6  print(f'after change,point y = {point.y}') #6

三、类的继承

ptyhon在实现继承时会用一个叫mro列表的算法实现,它有三条规则:1、子类会先于父类;2、多个父类会根据它们在列表中的顺序被检查;3、如果对下一个类有两个合法的选择,则返回第一个合法的父类;

3.1、单继承

class a:  def __init__(self):  self.x = 0  class b(a):  def __init__(self):  super().__init__() #这行需要注意,也可以不写,但不写时就不会调用父类的init方法  self.y = 1

3.2、多继承

class base:  def __init__(self):  print('call base.__init__')  class a(base):  def __init__(self):  base.__init__(self)  print('call a.__init__')    class b(base):  def __init__(self):  base.__init__(self)  print('call b.__init__')  """多继承的实现"""  class c(a,b):  def __init__(self):  a.__init__(self)  b.__init__(self)  print('call c.__init__')  c = c()  # call base.__init__  # call a.__init__  # call base.__init__  # call b.__init__  # call c.__init__

3.3、调用父类方法

class proxy:  def __init__(self, obj):  self._obj = obj    def __getattr__(self, name):  return getattr(self._obj, name)    def __setattr__(self, name, value):  if name.startswith('_'):  """调用父类方法"""  super().__setattr__(name, value)  else:  setattr(self._obj, name, value)    proxy = proxy({})  proxy.__setattr__("_name", "hm")

3.4、属性扩展

3.4.1、完全扩展

# 父类  class person:  def __init__(self, name):  self.name = name    # defined getter function, auto to call the sign name.setter when it be build  @property  def name(self):  return self._name    # defined setter function  @name.setter  def name(self, value):  if not isinstance(value, str):  raise typeerror('expected a string')  self._name = value    # defined deleter function  @name.deleter  def name(self):  raise attributeerror("can't delete attribute")    """子类"""  class subperson(person):  @property  def name(self):  print('getting name')  return super().name    @name.setter  def name(self, value):  print(f'setting name to {value}')  super(subperson, subperson).name.__set__(self, value)    @name.deleter  def name(self):  print('deleting name')  super(subperson, subperson).name.__delete__(self)    """测试"""  sub_person = subperson('guido')  print(f'name is: {sub_person.name}')

3.4.2、单独扩展

class subperson(person):  @person.name.getter  def name(self):  print('getting name')  return super().name # or super(subperson, subperson).name.__set__(self, value)  sub_p = subperson('bill')
#不能用property的原因是,property其实是get、set、del函数的集合,各有各的用处。下面才是正确的扩展方式,所以下面的代码是不工作的  class subperson(person):  @property # doesn't work  def name(self):  print('getting name')  return super().name  #如果要用property属性则要用下面的编码实现  class subperson(person):  @property  def name(self):  print('getting name')  return super().name  @name.setter  def name(self, value):  print(f'setting name to {value}')  super(subperson, subperson).name.__set__(self, value)  @name.deleter  def name(self):  print('deleting name')  super(subperson, subperson).name.__delete__(self)

四、类的调用

import time  class date:  # primary constructor  def __init__(self, year, month, day):  self.year = year  self.month = month  self.day = day  # alternate constructor  @classmethod  def today(cls):  t = time.localtime() #它接收一个class作为第一个参数,它被用来创建并返回最终的实例, 这个cls==__init__  return cls(t.tm_year, t.tm_mon, t.tm_mday)
"""普通调用"""  c = date(2010, 12, 12)    """类方法在继承中使用"""  class newdate(date):  pass  c = date.today() # creates an instance of date (cls=date)  d = newdate.today() # creates an instance of newdate (cls=newdate)

五、抽象类

from abc import abcmeta, abstractmethod  class istream(metaclass=abcmeta):  @abstractmethod  def read(self, max_bytes=-1):  pass  @abstractmethod  def write(self, data):  pass  """不能被实例化"""  #a = istream()    class socketstream(istream):  def read(self, max_bytes=-1):  pass  def write(self, data):  pass  """检查"""  def serialize(obj, stream):  if not isinstance(stream, istream):  raise typeerror('expected an istream')  pass

5.1、强制类型检查

from abc import abcmeta, abstractmethod  class istream(metaclass=abcmeta):  @abstractmethod  def read(self, max_bytes=-1):  pass  @abstractmethod  def write(self, data):  pass  import io  # register the built-in i/o classes as supporting our interface  istream.register(io.iobase)    # open a normal file and type check  f = none #open('test.txt')  print(f'f object is istream type: {isinstance(f, istream)}')  #f object is istream type: false

六、类的比较

from functools import total_ordering  class room:  def __init__(self, name, length, width):  self.name = name  self.length = length  self.width = width  self.square_feet = self.length * self.width  @total_ordering  class house:  def __init__(self, name, style):  self.name = name  self.style = style  self.rooms = list()  @property  def living_space_footage(self):  return sum(r.square_feet for r in self.rooms)  def add_room(self, room):  self.rooms.append(room)  def __str__(self):  return f'{self.name}: {self.living_space_footage} square foot {self.style}'  def __eq__(self, other):  return self.living_space_footage == other.living_space_footage    def __lt__(self, other):  return self.living_space_footage < other.living_space_footage  # build a few houses, and add rooms to them  h1 = house('h1', 'cape')  h1.add_room(room('master bedroom', 14, 21))  h1.add_room(room('living room', 18, 20))  h1.add_room(room('kitchen', 12, 16))  h1.add_room(room('office', 12, 12))    h2 = house('h2', 'ranch')  h2.add_room(room('master bedroom', 14, 21))  h2.add_room(room('living room', 18, 20))  h2.add_room(room('kitchen', 12, 16))    h3 = house('h3', 'split')  h3.add_room(room('master bedroom', 14, 21))  h3.add_room(room('living room', 18, 20))  h3.add_room(room('office', 12, 16))  h3.add_room(room('kitchen', 15, 17))  houses = [h1, h2, h3]    print(f'is {h1} bigger than {h2}: {h1 > h2}')  print(f'is {h2} smaller than {h3}: {h2 < h3}')  print(f'is {h2} greater than or equal to {h1}: {h2 >= h1}')  print(f'which one is biggest in houses: {max(houses)}')  print(f'which is smallest in houses: {min(houses)}')    """"""  # is h1: 990 square foot cape bigger than h2: 846 square foot ranch: true  # is h2: 846 square foot ranch smaller than h3: 1101 square foot split: true  # is h2: 846 square foot ranch greater than or equal to h1: 990 square foot cape: false  # which one is biggest in houses: h3: 1101 square foot split  # which is smallest in houses: h2: 846 square foot ranch  # """"""  class house:  def __eq__(self, other):  pass  def __lt__(self, other):  pass  # methods created by @total_ordering  __le__ = lambda self, other: self < other or self == other  __gt__ = lambda self, other: not (self < other or self == other)  __ge__ = lambda self, other: not (self < other)  __ne__ = lambda self, other: not self == other

到此这篇关于python类的定义继承调用比较方法技巧的文章就介绍到这了,更多相关python类的定义内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

需要了解更多python教程分享Python类的定义继承调用比较方法技巧,都可以关注python教程分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/pythontutorial/1116896.html

(0)
上一篇 2022年7月10日
下一篇 2022年7月10日

精彩推荐