我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python类的定义继承调用比较方法技巧

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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个核心属性访问操作的类,分别对应get\set\delete这三个特殊的方法。

# 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类的定义内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python类的定义继承调用比较方法技巧

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python类的定义继承调用方法有哪些

这篇文章主要讲解了“Python类的定义继承调用方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python类的定义继承调用方法有哪些”吧!一、类的约束# _开头: 私有变量;# _
2023-07-02

Python自定义类继承threading.Thread的方法

本篇内容介绍了“Python自定义类继承threading.Thread的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明1、使用th
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录