# 一 类属性(公有的/私有的),实例属性,类对象,实例对象,方法(类/实例/静态/常用魔术方法) # 只有实例方法才能用实例属性
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