一、类

  • 最简单的经典类结构
class 类名:
    pass
复制代码
1、定义一个类
class Money:
    pass
复制代码

类名规范: 驼峰命名法, 并且首字母大写

2、实例化一个对象
  • 创建一个对象, 最简单的方式就是类名后加上小括号
one = Money()       # 创建一个Money类的实例化对象
复制代码
  • 可以打印查看类和对象
print(Money)
print(one)

# 打印结果:
<class '__main__.Money'>
<__main__.Money object at 0x101dba588>
复制代码
3、关于类名
  • 上面的Money类
class Money:
    pass
复制代码
  • 其中的Money, 即表示类名, 又是一个变量
  • 我们先通过__name__, 可以查看Money的类名
print(Money.__name__)           # 打印结果: Money
复制代码
  • 定义一个新的变量, 接受Money的值
abc = Money
print(abc)
# 打印结果: <class '__main__.Money'>
复制代码
  • 使用abc创建一个对象
one = abc()
print(one)
# 打印结果: <__main__.Money object at 0x103d1f6d8>
复制代码
  • 可以给Money重新赋值
Money = 666
print(Money)            # 打印结果: 666
复制代码

结论: 在定义类的时候, 在内存中分配了一段空间, 用来存放类的信息, 同时又创建了一个与类同名的变量, 这个变量指向这个类

例如: 创建Money类时, 在内存中分配空间存放Money类的信息, 同时创建一个变量Money, 并且指向Money类, 我们可以创建变量abc, 来指向Money类。 然后直接使用abc可以创建Money类的实例化对象, 同时也可以将变量Money重新赋值

二、对象

  • 实例化对象: 在内存中分配一段空间存放对象信息
  • 我们可以使用一个变量指向这个对象, 通过变量使用对象
  • 所有的对象都有一个属性__calss__, 可以查看当前对象属于哪一个类
class Money:                # 定义类
    pass    
one = Money()               # 创建对象, 并使用变量one引用这个对象
print(one.__class__)        # 打印: <class '__main__.Money'>
复制代码
1、添加属性
  • 定义一个Person类, 并实例化对象p
class Person:
    pass
p = Person()
复制代码
  • 可以直接使用对象.属性 = 值, 给对象添加属性
p.name = "zhangsan"
p.age = 18
p.height = 1.78
复制代码
2、查询属性
  • 可以使用对象.__dict__查看对象所有的属性
result = p.__dict__
print(result)
# 打印结果: {'name': 'zhangsan', 'age': 18, 'height': 1.78}
复制代码
  • 可以使用对象.属性, 查看属性值
print(p.name)           # 打印: zhangsan
print(p.age)            # 打印: 18
print(p.height)         # 打印: 1.78
复制代码
  • 如果查看对象不存在的属性, 那么会直接报错
print(p.sex)
# 报错: AttributeError: 'Person' object has no attribute 'sex'
复制代码
3、修改属性
  • 可以使用对象.属性 = 值, 来修改属性
p.age = 20
复制代码
4、删除属性
  • 使用del语句, 可以删除对象已有属性
print(p.__dict__)
del p.name
print(p.__dict__)

# 打印结果:
{'name': 'zhangsan', 'age': 20, 'height': 1.78}
{'age': 20, 'height': 1.78}
复制代码
  • 删除所有属性
print(p.__dict__)
del p.__dict__
print(p.__dict__)

# 打印结果:
{'name': 'zhangsan', 'age': 18, 'height': 1.78}
{}
复制代码

三、类的属性

1、添加属性
  • a. 使用类.属性 = 值, 可以给类添加属性
class Money:
    pass
Money.count = 1
复制代码
  • b. 在类的实现中添加属性
class Money:
    count = 1
复制代码
2、查看属性
  • 使用类.属性, 可以获取属性值
print(Money.count)          # 打印: 1
复制代码
  • 可以使用类.__dict__查看类的所有属性
print(Money.__dict__)

# 打印结果:
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Money' objects>, '__weakref__': <attribute '__weakref__' of 'Money' objects>, '__doc__': None, 'count': 1}
复制代码

'count': 1就是新添加的类属性, 至于其他属性都是类创建时系统添加的类属性

  • 如果查看不存在的属性, 会报错
print(Money.number)
# 报错: AttributeError: type object 'Money' has no attribute 'number'
复制代码
3、使用对象访问类中的属性
  • 定义Money类, 并添加countnum属性
class Money:    
    count = 1
    num = 666
复制代码
  • 实例化一个对象
one = Money()
复制代码
  • 通过对象.类属性, 访问类中的countnum属性
print(one.count)            # 打印: 1
print(one.num)              # 打印: 666
复制代码

当访问对象的某个属性时

  1. 如果对象本身拥有这个属性, 会直接使用
  2. 当对象本身没有这个属性时, 就会根据自身的__class__属性, 找到对应的类, 然后在类中查找属性
  3. 注意: 对象的__class__属性值是可以更改的, 如果__class__指向了其他的类, 那么就会在更改后的类中查找属性
4、修改属性
  • 通过类.属性, 修改类的属性
class Money:
    count = 1
    num = 666
    
Money.count = 10

print(Money.count)          # 打印结果: 10
复制代码
  • 通过对象.类属性, 修改属性时, 只是给自己本身添加一个属性, 而不是修改类属性
class Money:
    count = 1
    num = 666

one = Money()           # 实例化对象 one
one.count = 10          # 给one添加属性count, 并赋值10
print(one.count)        # 打印one的属性count的值

two = Money()           # 实例化对象 two
print(two.count)        # 打印two的count属性
print(Money.count)      # 打印类Money的类属性count

# 打印结果
10                      # one添加count属性的值
1                       # two没有count属性, 查找Money中的count属性
1                       # 打印类Money中的属性count
复制代码
  • 类属性被对象共享, 当类属性的值改变时, 对象访问的类属性的值也会改变
class Money:
    count = 1
    
one = Money()
two = Money()
print(one.count)            # 打印: 1
print(two.count)            # 打印: 1

Money.count = 2             # 修改类属性为2

print(one.count)            # 打印: 2
print(two.count)            # 打印: 2
复制代码
5、删除属性
  • 使用del 类.类属性, 可以删除类的属性
del Money.count
复制代码

无法通过del 对象.类属性, 删除类的属性, del语句只能删除直系属性

  • 类属性删除前, 实例化对象是可以访问该类属性的, 如果删除了类属性, 对象就无法再访问该类属性
class Money:
    count = 1
    num = 666

one = Money()   

print(one.count)        # 删除前通过对象, 打印: 1

print(Money.count)      # 删除前通过类, 打印: 1

del Money.count         # 删除类属性 count

print(one.count)        # 报错: AttributeError: 'Money' object has no attribute 'count'
复制代码

不管是类, 还是对象, 添加的属性都是放在了__dict__中, 对象可以通过修改__dict__修改属性, 而类需要一些其他的方法修改

四、限制对象添加属性

  1. 由于Python中的对象可以添加任何属性, 所以就可能导致同一个类创建的对象, 拥有不同的属性, 这可能给开发带来一定的麻烦
  2. 所以我们在定义类的时候, 就需要限制: 该类的对象只能添加某一些属性
可以使用__slots__限制对象添加哪一些属性
  • 定义一个Person类, 指定__slots__的值
class Person:
    __slots__ = ["age", "name"]
复制代码
  • 创建一个Person类的对象
p = Person()
复制代码
  • p添加几个属性, 并运行程序
p.age = 10
p.name = "zhangsan"
p.height = 1.78     # 报错: AttributeError: 'Person' object has no attribute 'height'
复制代码
  • 可以发现, p在添加agename时没有问题, 但是在添加height时有问题
  • 这说明在类的定义中, 如果指定了__slots__的值, 那么实例化对象只能添加__slots__中的属性, 而不能添加其他属性