# 一 类属性(公有的/私有的),实例属性,类对象,实例对象,方法(类绑定/实例/静态/常用魔术方法) # 只有实例对象才能用实例属性

# 一 类属性(公有的/私有的),实例属性,类对象,实例对象,方法(类/实例/静态/常用魔术方法) # 只有实例方法才能用实例属性
class People:
    # 公有的类属性(公有的类数据属性)----- 类对象,实例对象都可以调用
    hobby = 'watch beauty'
    # 私有的类属性(私有的类数据属性)----类对象,实例对象都无法调用(通过特殊的方式调用)
    __pet_name = 'ai'
    # 私有的类属性(私有的类数据属性)----类对象,实例对象可以调用(不建议外部调用)
    _pet_age = 18

    # 魔术方法,初始化类{'really_name':'传入的值','really_age':'传入的值'}
    def __init__(self, really_name, really_age):
        # 第一种实例属性 实例属性----实例对象专属的,只能实例对象去赋值调用
        self.really_name = really_name
        self.really_age = really_age

    # print的时候自动触发,
    def __str__(self):
        return '真实姓名%s' % self.really_name

    # 实例方法
    def say(self):
        return 'name:%s' % self.really_name
    # 静态方法


# 类对象:类名
# 实例对象:类创建的对象
#
# 类对象 People.hobby
print('我是类对象', People.hobby)
# 实例对象 people
people = People(really_name='p1', really_age=18)
print('我是实例对象', people.hobby)
# 第二种 实例属性----实例对象专属的,只能实例对象去赋值调用
people.home = 'earth'
print('我是实例属性', people.home)
# 类对象无法调用实例属性 报错
# print(People.home)
# print(People.really_name)

# 实例方法---类对象调用手动传参
print(People.say(people))
# 实例方法---实例对象调用自动传参
print(people.say())


# 二 外部修改类属性
# 如果在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,
# 会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且如果通过
# 实例对象引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性

class People:
    name = '我是类属性'

    def __init__(self, really_name):
        self.really_name = really_name


# 修改

# 类对象修改
People.name = '我是类对象,验证我是否修改了类属性'
print('我是类对象', People.name)  # 我是类对象,类属性改变了
# 实例对象修改
people = People('我是实例对象')
people.name = '我是实例对象,验证我是否修改了类属性'
print('我是实例对象', people.name)  # 我是实例对象,我修改了类属性
print('我是类对象,', People.name)  # 我是类属性-----实例对象修改类属性的时候,类属性并没有改变


# 三 类方法
'''
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,
对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,
但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),
能够通过实例对象和类对象去访问。

'''


class People:
    name = '我是类属性'

    def __init__(self, really_name):
        self.really_name = really_name

    # 类方法
    @classmethod
    def eat(cls):
        return cls.name

    @classmethod
    def eat1(cls):
        a = '类属性被修改了,通过类方法'
        cls.name = a

    @classmethod
    def eat2(cls, a):
        cls.name = a


# # 类对象调用类方法-----------自动传参
# print('我是类对象', People.eat())  # 我是类对象,类属性改变了
# # 实例对象调用类方法-----------自动传参
# people = People('我是实例对象,手动传参')
# print(people.eat())

# # 类方法对类属性修改 不传参
# people = People('我是实例对象,手动传参')
# # 类对象调用类方法-----------自动传参
# print('我是类对象', People.eat1(), People.name)  # 我是类对象,类属性改变了
#
# # 实例对象调用类方法-----------自动传参
# print('我是实例对象',people.eat1(), people.name)

# 类方法对类属性修改 传参
people = People('我是实例对象,手动传参')
# 类对象调用类方法-----------自动传参
print('我是类对象', People.eat2('类方法传参'), People.name)  # 我是类对象,类属性改变了

# 实例对象调用类方法-----------自动传参
print('我是实例对象', people.eat2('类方法传参'), people.name)

# 四静态方法
# 需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

'''

从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,
那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,
那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用

'''
class People:
    name = '我是类属性'

    def __init__(self, really_name):
        self.really_name = really_name

    @staticmethod
    def eat3(c, d):
        return c, d


print(People.eat3(1, 2))
people = People('xx')
print(people.eat3(3, 4))


# 魔术方法
# 1. 魔术方法大全
https://zhuanlan.zhihu.com/p/329962624

# 2. __setattr__,setattr(),getattr__,getattr()及__getattribute__的区别
https://www.jianshu.com/p/1e60edf21794

https://blog.csdn.net/MrLevo520/article/details/51712875

'''
什么是魔术方法?
在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,
而魔术方法不需要调用就可以自动执行。

魔术方法在类或对象的某些事件出发后会自动执行,让类具有神奇的“魔力”。如果希望根据自己的程序定制自己特殊功能的类,
那么就需要对这些方法进行重写。

'''


class People:
    name = '我是类属性'

    # def __init__(self, really_name):
    #     self.really_name = really_name

    # def __str__(self):
    #     return self.really_name

    # 获取不到值会触发,可以进行默认操作
    def __getattr__(self, item):
        return setattr(people, item, 'acsml')

    # def __setattr__(self, key, value):
    #     if key == value:
    #         return 'key不能登录value'
    #     else:
    #         return 'set success'
    # def __setitem__(self, key, value):
    #     print('s')
    #     return setattr(people, key, value)

    # def __getitem__(self, item):
    #     return getattr(self, item)


# people = People('xxxxxx')
people = People()
# 有魔术方法执行魔术方法,不会在执行
# setattr(people, 'age', 18)
# people.a = 0
# print(people.age)
# print(hasattr(people, 'name'))
# print(people.__dir__())
print(people.l)
print(people.l)
# None
# acsml

 

posted @ 2021-10-13 13:20  mofr  阅读(36)  评论(0)    收藏  举报