python类的定义与实例化

  • Post author:
  • Post category:python


类的定义与实例化

在Python中,通过class关键字定义一个类,比如我们需要定义一个人的类。按照 Python 的编程习惯,类名以大写字母开头。因此可以这样定义:

 class Person:  pass

注意,在这个Person类的定义里面,并没有继承任何类,除了这样定义以外,还可以有以下两种定义方式。

 class Person(): pass 
 class Person(object):  pass

在python3中,这三种定义是没有区别的,

在Python2中,对于第一种定义的方法,Person类只有有限的几个内建函数’

doc

’, ‘

module

’, ‘name’,而对于第二种、第三种定义的方法,则会继承Python object对象的更多的内建函数,可以更便捷的操作对象。这是Python2版本的差异。

实例化:

把抽象的类,赋予实物的过程。

class Person(object):pass
SHeep=Person()
xioayang=Person()

实例属性的定义

赋予实例属性

Sheep.name='SHeep'
SHeep.sex='girl'
SHeep.age=18

print(Sheep.name)
print(SHeep.sex)
print(SHeep.age)

属性也可以进行计算

实例属性的初始化

在定义 Person 类时,可以为Person类添加一个特殊的__init__()方法,当创建实例时,

init

()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:

class Person(object):
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

需要注意的是,

init

() 方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法),后续参数则可以自由指定,和定义函数没有任何区别。

定义类后,就可以相应的实例化对象了,需要注意的是,在实例化的时候,需要提供除self以外的所有参数。

SHeep = Person('SHeep', 'boy', 13)
xiaoyang = Person('xiaoyang', 'girl', 14)

而访问这些属性的方式和之前的一样:

print(SHeep.name)
print(SHeep.sex)
print(SHeep.age)


**# 但当访问不存在的属性时,依然会报错**
print(SHeep.birth)

要特别注意的是,初学者定义__init__()方法常常忘记了 self 参数,比如如下的定义:

class Person(object):
    def __init__(name, sex, age):
        pass

这种情况下,如果还是如下实例化,将会报错。
xiaoming = Person('SHeep', 'boy', 13)
xiaohong = Person('xiaoyang', 'girl', 14)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes 3 positional arguments but 4 were given

类属性

类和实例的区别:类是抽象的,是模板;而实例,就是根据模板创造出来的对象。例如动物,是一个抽象,而猫猫是具体的动物,是动物类的对象。

实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例;同样的,类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。

定义类属性可以直接在 class 中定义,比如在Animal类中,加入地域的类属性:

class Animal(object):
    localtion = 'Asia'
    def __init__(self, name, age):
        self.name = name
        self.age = age

在上面的代码中,localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。

dog = Animal('wangwang', 1)
cat = Animal('mimi', 3)
print(dog.localtion) # ==> Asia
print(cat.localtion) # ==> Asia


#类属性,也可以通过类名直接访问


print(Animal.localtion) # ==> Asia

类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更:

Animal.localtion = 'Africa'
print(cat.localtion) # ==>Africa
print(dog.localtion) # ==>Africa

类属性和实例属性的优先级

属性可以分为类属性和实例属性,如果类属性和实例属性名字相同时,实例属性优先

在前面类定义的基础上,在实例属性中,也初始化一个localtion的属性。

class Animal(object):
    localtion = 'Asia'
    def __init__(self, name, age, localtion):
        self.name = name
        self.age = age
        self.localtion = localtion

接着我们初始化两个实例,并把localtion打印出来。

​dog = Animal('wangwang', 1, 'GuangDong')
cat = Animal('mimi', 3, 'ChongQing')
print(dog.localtion) # ==> GuangDong
print(cat.localtion) # ==> ChongQing
print(Animal.localtion) # ==> Asia

可见,在类属性和实例属性同时存在的情况下,实例属性的优先级是要高于类属性的,在操作实例的时候,优先是操作实例的属性。

另外,当实例没有和类同名的时候,通过实例对象,依然可以访问到类属性。

class Animal(object):
    localtion = 'Asia'
    def __init__(self, name, age):
        self.name = name
        self.age = age


cat = Animal('mimi', 3)
print(cat.localtion) # ==> Asia

那通过实例,可不可以修改类属性呢?我们来尝试一下:

cat.localtion = 'Africa'
print(Animal.localtion) # ==> Asia

这里依然打印了Asia,可见通过实例是无法修改类的属性的,事实上,通过实例方法修改类属性,只是给实例绑定了一个对应的实例属性:

​# 新增的实例属性

print(cat.localtion) # ==> Africa

因此,需要特别注意,尽量不要通过实例来修改类属性,否则很容易引发意想不到的错误。



版权声明:本文为qq_45681074原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。