文章目录
GitHub: https://github.com/RealEmperor/Basic-Introductory-Python-Course
类和实例
类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
实例变量:定义在方法中的变量,只作用于当前实例的类。
对“类”和“对象”的使用:
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能。
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。
# 创建类
class Foo:
# 类中的函数
def bar(self):
# 功能阐述
pass
# =====完毕========
# 根据Foo创建对象obj
obj = Foo()
# 创建对象的时候 记得后面加个括号
注意,按照Python通用规则,Class用驼峰式表示(HelloWorld)
而其他的obj等等,都用‘_’隔开(this_is_object)
类中的函数第一个参数必须是self,类中定义的函数叫做“方法”。
# 创建类
class Foo:
def bar(self):
print('Bar')
def hello(self, name):
print('i am %s' % name)
# 根据Foo创建的对象
obj = Foo()
obj.Bar() # 执行Bar方法
obj.Hello('july') # 执行Hello方法
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-d2c525f2bacd> in <module>()
11 # 根据Foo创建的对象
12 obj = Foo()
---> 13 obj.Bar() # 执行Bar方法
14 obj.Hello('july') # 执行Hello方法
AttributeError: 'Foo' object has no attribute 'Bar'
self 是个什么鬼呢?它是为了指代它所存在的类Class之中。
比如我们如果有好几个不同的obj被创建成同一个类,
那么有了self,我们的class Foo就能很好的知道哪个指的是自己,不会乱
# 创建类
class Foo:
# 这里我们可以创建一个类级别的变量
# 它不会随着由此类创建的变量而变化
name = 'Jan'
def bar(self):
print('Bar')
def hello(self, name):
print('you are %s' % self.name)
print('I am %s' % name)
print('\n')
# 根据Foo创建的对象
obj1 = Foo()
obj2 = Foo()
obj1.hello('August')
obj2.hello('July')
you are Jan
I am August
you are Jan
I am July
所以说,这个 self 就是个代指。代指了自己所在的class。你可以由 self 点进所指class本身的函数。由此可见,self 本身作为一个代词,并不一定要叫self。你也可以用个其他什么来代替。只不过,必须得是这个类的所有子方法的第一个参数:
# 创建类
class Foo:
# 这里我们可以创建一个类级别的变量
# 它不会随着由此类创建的变量而变化
name = 'Jan'
def bar(july):
print('Bar')
def hello(july, name): # 我这里把self改成了july,
# 但是只要它作为第一参数的位置没变,它依旧是Foo Class的自我指代
print('you are %s' %july.name)
print('I am %s' %name)
print('\n')
# 根据Foo创建的对象
obj1 = Foo()
obj2 = Foo()
obj1.hello('August')
obj2.hello('July')
you are Jan
I am August
you are Jan
I am July
构造函数:构造函数,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值。
跟所有OOP语言一样,python也是有构造函数的,默认为:
# 创建类
class Foo:
def __init__(self): # 这就是构造函数,它的职责是在模型创建的初期,就完成一些动作
# 简单的说就是,自定义的初始化步骤:
# 同样,它需要self来指代本身这个class
self.name = 'Jan'
def hello(self, name):
print('you are %s' % self.name)
print('I am %s' % name)
print('\n')
# ==== 完毕 =====
# 当你创建一个Foo类的时候,init会被自动跑一遍:
obj = Foo()
# 在我们的例子中,我们默认给self自己的name变量,赋值为’JAN‘
# 此刻,当我们调用Foo的hello()方法时,hello自己的name变量,被赋值为'July'
obj.hello('July')
you are Jan
I am July
init是可以带更多的参数的,用以初始化我们的class本身。
比如说,你要初始化一个类的时候要用到一些外部参数:
# 创建类
class Foo:
def __init__(self, name2): # 你可以在这里附加上一些参数
# 这些参数将是你创建一个Foo类时的必要条件
self.name = name2
def hello(self, name):
print('you are %s' % self.name)
print('I am %s' % name)
print('\n')
# ==== 完毕 =====
# 当你创建一个Foo类的时候,init会被自动跑一遍:
# 此刻,你不可以直接跑Foo(),你需要填入一个参数:name2
obj = Foo('Feb')
# 然后再调用hello, 并赋值July
obj.hello('July')
you are Feb
I am July
由楼上这些例子,我们大概可以知道整个Python的OOP概念了:
Class(类)就是一个把一堆Object(对象?)集合起来的地方。
在这里,无论是变量还是方法,他们享有基本一样的层级概念。只不过,方法要做一点事儿,而变量直接就是一个值。
访问限制
我们刚刚看到,在调用obj的时候,可以直接调出name或者使用hello()。那么我们怎么知道什么时候可以调用他们,什么时候不可以呢?
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线、__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
举个学生的例子,我们可以用一个学生类来存储学生的信息,但是我们在外部可以接触到name,那么其实我们就是可以直接修改name的,这是不安全的
class Student: