对象属性和类属性

类属性:尽量用 类名.类属性来修改和调用
对象属性: 用 对象.对象属性来修改和调用

class Dog:
    # 类属性
    name = '八公'
    age = 16
    likes = ['骨头']

    def __init__(self, color, name):
        # 对象属性
        self.color = color
        self.name = name
        self.likes2 = ['骨头']
# 对象
dog1 = Dog('黄色', '忠犬八公')
# 获取属性值
# print(dog1.name)  # 对象.类属性
# print(dog1.color)  # 对象.对象属性

# print(Dog.name)  # 类.类属性
# print(Dog.color)  # 类.对象属性, 会报错

# 修改属性:
#   类属性:尽量用 类名.类属性来修改
#   对象属性: 用 对象.对象属性来修改
# Dog.age = 6  # 类.类属性 修改的是类属性
# dog1.age = 6  # 新增了一个对象属性age:动态添加属性
# print(dog1.age, Dog.age)  # 6 16
#
# dog1.color = 'green'
# Dog.color = 'green'
# print(dog1.color)

# 对象属性和类属性有同名的情况下
# 查询属性值
# print(dog1.name)  # '忠犬八公' 会优先获取对象属性
# print(Dog.name)  # '八公'

# dog1.name = '旺财'
# print(dog1.name, Dog.name)  # 旺财 八公
Dog.name = '旺财'
print(dog1.name, Dog.name)  # 忠犬八公 旺财


# 类属性: 可变类型是共享的
d1 = Dog('白色', '小白')
d2 = Dog('黑色', '小黑')

print(d1.likes)  # ['骨头']
print(d2.likes)  # ['骨头']

d1.likes.append('狗粮')
print(d1.likes)  # ['骨头', '狗粮']
print(d2.likes)  # ['骨头', '狗粮']
print('-' * 60)

# 对象属性: 内存独立的
d1 = Dog('白色', '小白')
d2 = Dog('黑色', '小黑')

print(d1.likes2)  # ['骨头']
print(d2.likes2)  # ['骨头']

d1.likes2.append('狗粮')
print(d1.likes2)  # ['骨头', '狗粮']
print(d2.likes2)  # ['骨头']

私有属性

(了解)

import  datetime
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.__money = 1000  # 以两个下划线开始的变量是私有变量

    def add(self):
        self.__money += 1000 #在类里可以直接访问私有变量

    def get_money(self):
        print('{}查询了余额'.format(datetime.datetime.now()))
        return self.__money
    def set_money(self,qian):
        if type(qian) !=int:
            print('输入的钱的格式不对')
            return
        self.__money = qian

    def __demo(self):# 以两个下划线开头的函数是私有函数
        print('我是私有函数我被调用了')

    def text(self):
        self.__demo()



p = Person('张三', 18)
print(p.name, p.age)  # 可以直接获取
# print(p.__money)  # 不能直接获取到私有变量
# p.__demo()# 不能直接调用

# 获取私有变量的方式:
# 1.使用对象._类名__私有变量名获取和改变
p._Person__money = 500
print(p._Person__money)# 500
p._Person__demo()# 我是私有函数我被调用了
# 2.也可以通过定义方法来获取和改变私有属性
print(p.get_money())
# 2021-01-20 13:10:38.110169查询了余额
# 500
p.set_money(100)
print(p.get_money())
# 2021-01-20 13:10:38.110169查询了余额
# 100

# 定义函数来返回私有函数
p.text()# 我是私有函数我被调用了

类方法和静态方法

(和函数差不多,无非就是无参函数和有参函数,理解起来还是比较简单的)

class Person(object):
    type='人类'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self, food):
        print(self.name + '正在吃' + food)

    #如果方法里没有用到实例对象的任何属性,可以将这个方法定义成为一个静态方法
    @staticmethod
    def demo():
        print('hello')

    @classmethod
    def text(cls):# 如果这个方法只用到了类属性,可以将这个方法定义为类方法
        # 类方法有一个参数cls,不需要手动传递参数,会自动传参
        # cls 指的是类对象,  cls == Person ==True
        print(cls.type)

p = Person('张三', 18)
p1 = Person('李四',19)
# 实例对象在调用方法时,不需要给形参self传递参数
# 会自动的把实例对象传给self
p.eat('屎')  # 直接使用实例对象调用方法

# 对象方法还可以使用类对象来调用 格式:类名.方法名
# 这种方法不会自动的给self传递参数,需要手动的给self传参
Person.eat(p1,'奥利给')

# 静态方法:没有用到实例对象的任何属性
Person.demo()
p.demo()

# 类方法:
# 可以使用实例对象和类对象调用
p.text()
Person.text()


一起加油