精选文章 Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)

Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)

作者:幽楼 时间: 2021-02-05 09:43:12
幽楼 2021-02-05 09:43:12
【摘要】类与对象 
1. 对象 = 属性 + 方法 
对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。 
封装:信息隐蔽技术 
我们可以使用关键字 class 定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。 
class Turtle:  # Python中的类名约定以大写字母开头 """关于类的一个简单...

类与对象

1. 对象 = 属性 + 方法

对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

封装:信息隐蔽技术

我们可以使用关键字 class 定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。

class Turtle:  # Python中的类名约定以大写字母开头 """关于类的一个简单例子""" # 属性 color = 'green' weight = 10 legs = 4 shell = True mouth = '大嘴' # 方法 def climb(self): print('我正在很努力的向前爬...') def run(self): print('我正在飞快的向前跑...') def bite(self): print('咬死你咬死你!!') def eat(self): print('有得吃,真满足...') def sleep(self): print('困了,睡了,晚安,zzz')


tt = Turtle()
print(tt)
# <__main__.Turtle object at 0x0000007C32D67F98>

print(type(tt))
# 

print(tt.__class__)
# 

print(tt.__class__.__name__)
# Turtle

tt.climb()
# 我正在很努力的向前爬...

tt.run()
# 我正在飞快的向前跑...

tt.bite()
# 咬死你咬死你!!

# Python类也是对象。它们是type的实例
print(type(Turtle))
# 

继承:子类自动共享父类之间数据和方法的机制

class MyList(list): pass


lst = MyList([1, 5, 2, 7, 8])
lst.append(9)
lst.sort()
print(lst)

# [1, 2, 5, 7, 8, 9]

多态:不同对象对同一方法响应不同的行动

class Animal: def run(self): raise AttributeError('子类必须实现这个方法')


class People(Animal): def run(self): print('人正在走')


class Pig(Animal): def run(self): print('pig is walking')


class Dog(Animal): def run(self): print('dog is running')


def func(animal): animal.run()


func(Pig())
# pig is walking

2. self 是什么?

Python 的 self 相当于 C++ 的 this 指针。

class Test: def prt(self): print(self) print(self.__class__)


t = Test()
t.prt()
# <__main__.Test object at 0x000000BC5A351208>
# 

类的方法与普通的函数只有一个特别的区别 —— 它们必须有一个额外的第一个参数名称(对应于该实例,即该对象本身),按照惯例它的名称是 self。在调用方法时,我们无需明确提供与参数 self 相对应的参数。

class Ball: def setName(self, name): self.name = name def kick(self): print("我叫%s,该死的,谁踢我..." % self.name)


a = Ball()
a.setName("球A")
b = Ball()
b.setName("球B")
c = Ball()
c.setName("球C")
a.kick()
# 我叫球A,该死的,谁踢我...
b.kick()
# 我叫球B,该死的,谁踢我...

3. Python 的魔法方法

据说,Python 的对象天生拥有一些神奇的方法,它们是面向对象的 Python 的一切...

它们是可以给你的类增加魔力的特殊方法...

如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,而这一切都是自动发生的...

类有一个名为 __init__(self[, param1, param2...]) 的魔法方法,该方法在类实例化时会自动调用。

4. 公有和私有

在 Python 中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。

类的私有属性实例

class JustCounter: __secretCount = 0  # 私有变量 publicCount = 0  # 公开变量 def count(self): self.__secretCount += 1 self.publicCount += 1 print(self.__secretCount)


counter = JustCounter()
counter.count()  # 1
counter.count()  # 2
print(counter.publicCount)  # 2

print(counter._JustCounter__secretCount)  # 2 Python的私有为伪私有
print(counter.__secretCount)  
# AttributeError: 'JustCounter' object has no attribute '__secretCount'

类的私有方法实例

class Site: def __init__(self, name, url): self.name = name  # public self.__url = url  # private def who(self): print('name  : ', self.name) print('url : ', self.__url) def __foo(self):  # 私有方法 print('这是私有方法') def foo(self):  # 公共方法 print('这是公共方法') self.__foo()


x = Site('老马的程序人生', 'https://blog.csdn.net/LSGO_MYP')
x.who()
# name  :  老马的程序人生
# url :  https://blog.csdn.net/LSGO_MYP

x.foo()
# 这是公共方法
# 这是私有方法

x.__foo()
# AttributeError: 'Site' object has no attribute '__foo'

5. 继承

Python 同样支持类的继承,派生类的定义如下所示:

class DerivedClassName(BaseClassName):  . . . 

BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

class DerivedClassName(modname.BaseClassName):  . . . 

如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。

# 类定义
class people: # 定义基本属性 name = '' age = 0 # 定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 # 定义构造方法 def __init__(self, n, a, w): self.name = n self.age = a self.__weight = w def speak(self): print("%s 说: 我 %d 岁。" % (self.name, self.age))


# 单继承示例
class student(people): grade = '' def __init__(self, n, a, w, g): # 调用父类的构函 people.__init__(self, n, a, w) self.grade = g # 覆写父类的方法 def speak(self): print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))


s = student('小马的程序人生', 10, 60, 3)
s.speak()
# 小马的程序人生 说: 我 10 岁了,我在读 3 年级

注意:如果上面的程序去掉:people.__init__(self, n, a, w),则输出: 说: 我 0 岁了,我在读 3 年级,因为子类的构造方法把父类的构造方法覆盖了。

解决该问题可用以下两种方式:

调用未绑定的父类方法Fish.__init__(self)

使用super函数super().__init__()


Python 虽然支持多继承的形式,但我们一般不使用多继承,因为容易引起混乱。

class DerivedClassName(Base1, Base2, Base3):  . . . 

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法

6. 组合

class Turtle: def __init__(self, x): self.num = x


class Fish: def __init__(self, x): self.num = x


class Pool: def __init__(self, x, y): self.turtle = Turtle(x) self.fish = Fish(y) def print_num(self): print("水池里面有乌龟%s只,小鱼%s条" % (self.turtle.num, self.fish.num))


p = Pool(2, 3)
p.print_num()
# 水池里面有乌龟2只,小鱼3条

7. 类、类对象和实例对象

Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)1

类对象:创建一个类,其实也是一个对象也在内存开辟了一块空间,称为类对象,类对象只有一个。

# 类对象
class A(object): pass

实例对象:就是通过实例化类创建的对象,称为实例对象,实例对象可以有多个。

# 实例化对象 a、b、c都属于实例对象。
a = A()
b = A()
c = A()

类属性:类里面方法外面定义的变量称为类属性。类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。

class A(): a = 0  # 类属性 def __init__(self, xx): # 使用类属性可以通过 (类名.类属性)调用。 A.a = xx

实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另外一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他的对象不能直接使用,因为self是谁调用,它的值就属于该对象。

class 类名(): __init__(self): self.name = xx #实例属性

类属性和实例属性区别

类属性:类外面,可以通过实例对象.类属性和类名.类属性进行调用。类里面,通过self.类属性和类名.类属性进行调用。
实例属性 :类外面,可以通过实例对象.实例属性调用。类里面,通过self.实例属性调用。
实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。
类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。

# 创建类对象
class Test(object): class_attr = 100  # 类属性 def __init__(self): self.sl_attr = 100  # 实例属性 def func(self): print('类对象.类属性的值:', Test.class_attr)  # 调用类属性 print('self.类属性的值', self.class_attr)  # 相当于把类属性 变成实例属性 print('self.实例属性的值', self.sl_attr)  # 调用实例属性


a = Test()
a.func()

# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100

b = Test()
b.func()

# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100

a.class_attr = 200
a.sl_attr = 200
a.func()

# 类对象.类属性的值: 100
# self.类属性的值 200
# self.实例属性的值 200

b.func()

# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100

Test.class_attr = 300
a.func()

# 类对象.类属性的值: 300
# self.类属性的值 200
# self.实例属性的值 200

b.func()
# 类对象.类属性的值: 300
# self.类属性的值 300
# self.实例属性的值 100

注意:属性与方法名相同,属性会覆盖方法。

class A: def x(self): print('x_man')


aa = A()
aa.x()  # x_man
aa.x = 1
print(aa.x)  # 1
aa.x()
# TypeError: 'int' object is not callable

8. 什么是绑定?

Python 严格要求方法需要有实例才能被调用,这种限制其实就是 Python 所谓的绑定概念。

Python 对象的数据属性通常存储在名为.__ dict__的字典中,我们可以直接访问__dict__,或利用 Python 的内置函数vars()获取.__ dict__。

class CC: def setXY(self, x, y): self.x = x self.y = y def printXY(self): print(self.x, self.y)


dd = CC()
print(dd.__dict__)
# {}

print(vars(dd))
# {}

print(CC.__dict__)
# {'__module__': '__main__', 'setXY': , 'printXY': , '__dict__': , '__weakref__': , '__doc__': None}

dd.setXY(4, 5)
print(dd.__dict__)
# {'x': 4, 'y': 5}

print(vars(CC))
# {'__module__': '__main__', 'setXY': , 'printXY': , '__dict__': , '__weakref__': , '__doc__': None}

print(CC.__dict__)
# {'__module__': '__main__', 'setXY': , 'printXY': , '__dict__': , '__weakref__': , '__doc__': None}

9. 一些相关的内置函数(BIF)

issubclass(class, classinfo) 方法用于判断参数 class 是否是类型参数 classinfo 的子类。
一个类被认为是其自身的子类。
classinfo可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True。

class A: pass


class B(A): pass


print(issubclass(B, A))  # True
print(issubclass(B, B))  # True
print(issubclass(A, B))  # False
print(issubclass(B, object))  # True

isinstance(object, classinfo) 方法用于判断一个对象是否是一个已知的类型,类似type()
type()不会认为子类是一种父类类型,不考虑继承关系。
isinstance()会认为子类是一种父类类型,考虑继承关系。

*** type()不会认为子类是一种父类类型,isinstance会认为子类是一种父类类型 ***


如果第一个参数不是对象,则永远返回False
如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。

a = 2
print(isinstance(a, int))  # True
print(isinstance(a, str))  # False
print(isinstance(a, (str, int, list)))  # True


class A: pass


class B(A): pass


print(isinstance(A(), A))  # True
print(type(A()) == A)  # True
print(isinstance(B(), A))  # True
print(type(B()) == A)  # False

hasattr(object, name)用于判断对象是否包含对应的属性。

class Coordinate: x = 10 y = -5 z = 0


point1 = Coordinate()
print(hasattr(point1, 'x'))  # True
print(hasattr(point1, 'y'))  # True
print(hasattr(point1, 'z'))  # True
print(hasattr(point1, 'no'))  # False

getattr(object, name[, default])用于返回一个对象属性值。

class A(object): bar = 1


a = A()
print(getattr(a, 'bar'))  # 1
print(getattr(a, 'bar2', 3))  # 3
print(getattr(a, 'bar2'))
# AttributeError: 'A' object has no attribute 'bar2'

setattr(object, name, value)对应函数 getattr(),用于设置属性值,该属性不一定是存在的。

class A(object): bar = 1


a = A()
print(getattr(a, 'bar'))  # 1
setattr(a, 'bar', 5)
print(a.bar)  # 5
setattr(a, "age", 28)
print(a.age)  # 28

delattr(object, name)用于删除属性。

class Coordinate: x = 10 y = -5 z = 0


point1 = Coordinate()

print('x = ', point1.x)  # x =  10
print('y = ', point1.y)  # y =  -5
print('z = ', point1.z)  # z =  0

delattr(Coordinate, 'z')

print('--删除 z 属性后--')  # --删除 z 属性后--
print('x = ', point1.x)  # x =  10
print('y = ', point1.y)  # y =  -5

# 触发错误
print('z = ', point1.z)
# AttributeError: 'Coordinate' object has no attribute 'z'

class property([fget[, fset[, fdel[, doc]]]]) 用于在新式类中返回属性值。
fget -- 获取属性值的函数
fset -- 设置属性值的函数
fdel -- 删除属性值函数
doc -- 属性描述信息

class C(object): def __init__(self): self.__x = None def getx(self): return self.__x def setx(self, value): self.__x = value def delx(self): del self.__x x = property(getx, setx, delx, "I'm the 'x' property.")


cc = C()
cc.x = 2
print(cc.x)  # 2

del cc.x
print(cc.x)
# AttributeError: 'C' object has no attribute '_C__x'

练习题

1、以下类定义中哪些是类属性,哪些是实例属性?

class C: num = 0 def __init__(self): self.x = 4 self.y = 5 C.count = 6

2、怎么定义私有⽅法?

3、尝试执行以下代码,并解释错误原因:

class C: def myFun(): print('Hello!') c = C() c.myFun()

4、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。

要求:

  • 平日票价100元
  • 周末票价为平日的120%
  • 儿童票半价
class Ticket(): # your code here

魔法方法(不太看得懂,只有__init__明白一点)

https://github.com/datawhalechina/team-learning-program/blob/master/PythonLanguage/14.%20%E9%AD%94%E6%B3%95%E6%96%B9%E6%B3%95.md

魔法方法总是被双下划线包围,例如__init__。

魔法方法的“魔力”体现在它们总能够在适当的时候被自动调用。

魔法方法的第一个参数应为cls(类方法) 或者self(实例方法)。

cls:代表一个类的名称
self:代表一个实例对象的名称

1. 基本的魔法方法

__init__(self[, ...]) 构造器,当一个实例被创建的时候调用的初始化方法

__new__(cls[, ...]) 在一个对象实例化的时候所调用的第一个方法,在调用__init__初始化前,先调用__new__。
__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__。
__new__对当前类进行了实例化,并将实例返回,传给__init__的self。但是,执行了__new__,并不一定会进入__init__,只有__new__返回了,当前类cls的实例,当前类的__init__才会进入。

 

 

 

 

 

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:Kotlin学习之协程

下一篇:HBase + Phoenix + SQuirreL SQL Client + JavaAPI

您可能感兴趣

  • Python实用脚本(1):读取Properties文件

    JAVA本身提供了对于Properties文件操作的类,项目中的很多配置信息都是放在了Properties文件。但是Python并没有提供操作Properties文件的库,所以,自己动手写个一个可以加载Properties文件的脚本。 class Properties:     fileName = ''     def...

  • Python爬虫urllib模块

    Python爬虫练习(urllib模块) 关注公众号“轻松学编程”了解更多。 1、获取百度首页数据 流程:a.设置请求地址 b.设置请求时间 c.获取响应(对响应进行解码) ''' 获取百度首页 ''' imp...

  • 【python学习笔记】字典

    1.字典的含义 ① 字典是python中唯一的映射类型 ② python的字典为键值对,有些地方称为hash,有些地方称之为关系数组 ③ 映射类型区别于序列类型,序列类型以数组的方式进行存储,通过索引的方式获取相对应位置的值,一般索引与对应位置存储的数据毫无关系 2.创建和访问字典 ① 空字典 >>> empty = {} >>> type(empt...

  • 选择黑盒测试用例设计方法的综合策略

    具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法、场景法等。这些方法都是比较实用的,但在具体工作中要采用什么方法,需要针对项目的特点加以适当的选择。在实际高水平的测试中,往往需要综合使用各种方法以有效的提高测试效率和测试覆盖度。 ...

  • 记不住但是实用的java方法

    一、字符串转换方法     1、toString,需要保证调用这个方法的类、方法、变量不为null,否则会报空指针。    2、String.valueOf。这个方法在使用的时候是有些特殊的。一般情况下,如果是确定类型的null传入,返回的是字符         串“null”,而如果直接传入null,则会发生错误     3、(String) 字符...

  • Arthas 临时执行线上 SpringBoot 项目Jar包的静态方法

    目标:     使用 Arthas 执行 SpringBoot 项目 Jar 包中 com.kwok.schedule.task.ESHisIndexParseTask 类中 parse() 静态方法。 注:     由于 SpringBoot 项目 Jar 包 ClassLoader 为 org.springframework.boot.load...

  • python的math库函数汇总

    目录 一、math库介绍二、math库使用三、math库函数3.1 math库的数字常数(4个)3.2 math库的数值表示函数(16个)3.3 math库的幂对数函数(8个)3.4 math库的三角运算函数(...

  • Windows防火墙开启ping,禁ping的配置方法

    当我通过本机Ping另一台在同一局域网内(即在同一网段)的计算机时,发现,如果防火墙开启的话,无论如何也ping不通。一旦关闭防火墙就可以ping通了。这是为什么呢?究竟该怎么设置呢?原因是这样的,现在的计算机系统,出于安全考虑,在默认情况下是不允许外部主机对其进行ping测试的。但在一个安全的局域网环境中,Ping测试又是管理员进行网络测试所必...

CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)介绍:华为云为您免费提供Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)在博客、论坛、帮助中心等栏目的相关文章,同时还可以通过 站内搜索 查询更多Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)的相关内容。| 移动地址: Python编程基础 Datawhale Task07:类、对象与魔法方法(3天) | 写博客