Python Crash Course读书笔记 - 第9章:CLASSES

单身狗小心了,本章进入面向对象编程。
Class称为类,Object称为对象,类的实例称为对象。

创建和使用Class

看一个简单定义:

class User:
    def __init__(self, name, age):
        self.name = name;
        self.age = age;

    def get_name(self):
        print(f"Name is {self.name}.")

    def get_age(self):
        print(f"Age is {self.age}.")

user1 = User('tom', 20)
user1.get_name()
user1.get_age()

print(f"name is {user1.name}, age is {user1.age}.")
user1.age = 100
print(f"name is {user1.name}, age is {user1.age}.")

__init__是Class的初始化方法,只能有一个。
Class中所有方法都必须至少有一个参数,这个参数而且必须是第一个参数,指向本对象。
换句话说,当调用方法时,Class都会将指向对象的指针作为第一个参数传入方法。在本例中,即self,这类似于Java中的this。但self并非关键字,你可以换成别的变量名,不过无论如何,它都指向本对象。

name和age都是此Class的属性,Class的属性可以直接访问和修改,这点倒是和Java不同。Python并没有public和·private`属性之分。

Class和实例

关于属性的默认值,可以在参数部分不包括此属性,然后在方法主体中直接设置此属性即可。
也可以在参数列表中指定默认值:

def __init__(self, status=True):

前面已经说过,对象的属性可以通过方法访问(如果需要复杂的规则),也可以直接用对象名+.访问。

对象可以作为函数的参数,而且和List和Dictionary一样,是传递reference的,因此可以在函数体内修改:

$ cat user.py
class User:
    def __init__(self, name, age):
        self.name = name;
        self.age = age;

def print_user(user):
    print(f"name: {user.name}, age:{user.age}")

def add_age(user):
    user.age += 1

user1 = User("tom", 18)
print_user(user1)
add_age(user1)
print_user(user1)

$ python3 user.py
name: tom, age:18
name: tom, age:19

继承

子类继承父类的所有属性和方法,子类可以定义自己的属性和方法。

$ cat superuser.py
class User:
    def __init__(self, name, age):
        self.name = name;
        self.age = age;

    def get_name(self):
        print(f"Name is {self.name}.")

    def get_age(self):
        print(f"Age is {self.age}.")


class SuperUser(User):
    def __init__(self, name, age, isvip):
        super().__init__(name, age)
        self.isvip = True

    def is_vip(self):
        print(f"user {self.name} is VIP.")

s = SuperUser('amy', 16, True)
s.get_name()
s.get_age()
s.is_vip()
$
$ python3 superuser.py
Name is amy.
Age is 16.
user amy is VIP.

父类和子类的定义必须在同一文件,并且父类的定义必须在前。
定义子类时,父类的名字必须在括号中,例如class SuperUser(User)
子类通过super()可以调用父类中的方法,通常需要调用父类的初始化方法,如super().__init__(name, age)。如果不调用的化,就必须自己做初始化。

父类中的方法在子类中可以覆盖(override),也就是方法名和参数个数相同:

class SuperUser(User):
...
    def get_name(self):
        print(f"Name is VIP:{self.name}.")
...

此外,重载(overload,指方法名一样,参数不一样)也是支持的,例如:

...
    def get_name(self, comment):
        super().get_name()
        print(f"Name is VIP:{self.name}.")
        print(comment)
...

对象可以作为对象的属性。

导入Class

和函数一样,Class也可以在单独文件中定义,然后利用import导入,形式如下。

from module import class1, class2, ..., classN

和函数一样,以下导入所有函数的写法不建议:

from module import *

可以加别名:

from super_man import SuperMan as SM

示例:

$ cat user.py
class User:
    def __init__(self, name, age):
        self.name = name;
        self.age = age;

    def get_name(self):
        print(f"Name is {self.name}.")

    def get_age(self):
        print(f"Age is {self.age}.")
$ cat superuser.py
from user import User

class SuperUser(User):
    def __init__(self, name, age, isvip):
        super().__init__(name, age)
        self.isvip = True

    def get_name(self):
        print(f"Name is VIP:{self.name}.")

    def is_vip(self):
        print(f"user {self.name} is VIP.")

s = SuperUser('amy', 16, True)
s.get_name()
$ python3 superuser.py
Name is VIP:amy.

如果导入的Class较多,也可以导入整个module:

import module

此时在调用Class时就需要加上模块名,例如module.ClassName

Python标准库

指包含在安装中的module,通过import就可以使用。
例如:

>>> from random import randint
>>> randint(1,100)
88

或者:

>>> import random
>>> random.randint(1, 100)
66
>>> randinit(1, 100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'randinit' is not defined

另一个示例:

>>> from random import choice
>>> suits = ['heart', 'diamond', 'club', 'spade']
>>> selected = choice(suits)
>>> selected
'spade'

Class风格

Class的名称遵循CamelCase,类似于驼峰,每个单词的首字母大写,并且不含大小写,例如SuperMan
实例和module的名字应小写,单词间用下划线_分割。
和函数和方法一样,Class和module都应包括docstring描述。
在Class内部,用单空行分隔方法。
在module内部,用双空行分隔Class。
需要引入标准库时,import语句放在文件首,然后下接空行,再import自己写的库。

发布了370 篇原创文章 · 获赞 43 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/stevensxiao/article/details/104002417