python的面向对象

在类的外部不能根据对象名.私有属性名 进行调用

__new__()方法自动被调用 先调用NEW 后调用init;

类方法可以获取类的私有属性
在实例方法中可以通过self修改私有属性,如果私有属性是类属性,则修改的不是类属性,而是新添加了一个私有属性
在类方法中使用cls也可以获取类的私有属性

静态方法:
调用时是 类名.类属性名!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
通常用于我们工作中遇到的相对来讲比较固定的打印输出操作或者请求操作
在里面可以写:return 类名.变量名

特点:
1、没有参数,而类方法的参数是cls,实例方法的参数是self

类方法调用时cls.类属性名


类方法和实例方法的区别
加了@classmethod装饰器的就是类方法
类方法第一个参数是cls 实例方法第一个参数是self

===================================================================================================================
taidamier=info()
print(taidamier) # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
print(id(taidamier)) # id(taidamier) 则是内存地址的十进制形式表示

——————————————————————————————————————————————————————————

凡是self.变量名 在类里面任何一个实例方法都可以调用
方法是:self.变量名 在对象里 调用方法是: 对象名.变量名 只有实例方法调用过后里面定义的self.变量名才存在

——————————————————————————————————————————————————————————
_str_()方法:
如果没有_str_则默认打印对象在内存的地址,有则打印出返回值
例如:
class lei(object):
'''类注释内容'''
def __init__(self,age):
self.name='师玲珑'
self.age=age
def add(self,sex):
self.sex=sex
def shu(self):
print(self.name,self.age,self.sex)
def __str__(self):
return '姓名为:%s'%self.name
xiang=lei(18)
print(xiang)
结果为:姓名为:师玲珑

查看类注释:
print(对象名._doc_) 要主要注释内容的位置 和注释方式是多行注释 和函数里查看注释一样
——————————————————————————————————————————————————————————
_del_方法
在类里面也是和_init_一样自动被调用如果在对象接收了类后 del(对象名) _del_里的内容最后执行

——————————————————————————————————————————————————————————
class People(object):
address = '山东' # 类属性
def __init__(self):
self.name = 'xiaowang' # 实例属性
self.age = 20 # 实例属性

p = People()
p.age = 12 # 实例属性
print(p.address) # 正确
print(p.name) # 正确
print(p.age) # 正确

print(People.address) # 正确
print(People.name) # 错误
print(People.age) # 错误

——————————————————————————----——————————————————————————————————————————————
class People(object):
country = 'china' #类属性
def __init__(self):
self.country='123'

print(People.country)
p = People() #实例化对象
print(p.country)
p.country = 'japan'
print(p.country) # 实例属性会屏蔽掉同名的类属性
print(People.country)
del p.country # 删除实例属性 ===============================
print(p.country)
print(People.country)

结果为
china
123
japan
china
china
china
——————————————————————————----——————————————————————————————————————————————
类属性不能被修改 实例属性会覆盖类属性,重名后修改的也是实例属性 删除也是
如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。

——————————————————————————----——————————————————————————————————————————————
类方法还有一个用途就是可以对类属性进行修改:
class People(object):
# 私有类属性
__country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def get_country(cls):
return cls.__country
@classmethod
def set_country(cls,country):
cls.__country = country

p = People()
print(p.get_country()) #可以用过实例对象访问
print(People.get_country()) #可以通过类访问
p.set_country('japan')
print(p.get_country())
print(People.get_country())
结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变

——————————————————————————----——————————————————————————————————————————————
从类方法和实例方法以及静态方法的定义形式就可以看出来,

1、类方法的第一个参数是类对象cls,那么通过cls引用的必定是(类对象的属性和方法) ; @classmethod
不是实例,是类

2、实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
可能是实例可能是类

3、静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引用 @staticmethod
只能调用类属性 里面方式是:类名.类属性名 不能调用self.变量名 报错
——————————————————————————----——————————————————————————————————————————————

__init__()方法

# Python 的类里提供的,两个下划线开始,两个下划线结束的方法,就是魔法方法,__init__()就是一个魔法方法,通常用来做属性初始化 或 赋值 操作。
# 如果类面没有写__init__方法,Python会自动创建,但是不执行任何操作,
# 如果为了能够在完成自己想要的功能,可以自己定义__init__方法,
# 所以一个类里无论自己是否编写__init__方法 一定有__init__方法。
说明:
__init__()方法,在创建一个对象时默认被调用,不需要手动调用
__init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去

1). 在类内部获取 属性 和 实例方法,通过self获取;
2). 在类外部获取 属性 和 实例方法,通过对象名获取。
3). 如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址;
4). 但是实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法。
(3)、(4)区别如下 例如:
class Lol(object):
def __init__(self,hp,name,atk):
self.hp=hp
self.fyl=50
def shu(self):
print(self.hp)
def dizhi(self):
print(id(self.fyl))
def dizhi2(self):
print(id(self.hp))j
jie=Lol(100)
anqila=Lol(200)
jie.dizhi()
anqila.dizhi()
jie.dizhi2()
anqila.dizhi2()
返回的结果 dizhi的两个结果相同 dizhi2返回的结果不同
——————————————————————————————————————————————————————————————————————————

多继承可以继承多个父类,也继承了所有父类的属性和方法
注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)
多个父类中,不重名的属性和方法,不会有任何影响。
如果子类和父类的方法名和属性名相同,则默认使用子类的

如果重名后还想调用父类的实例方法 调用时:
父类名.实例方法名() 下面在写重复的名字 数值就是该父类的该实例方法里的值了

——————————————————————————————————————————————————————————————————————————

1). 私有属性,可以在类内部通过self调用,但不能通过对象访问
2). 私有方法,可以在类内部通过self调用,但不能通过对象访问
3). 对象不能访问私有权限的属性和方法
4). 子类不能继承父类私有权限的属性和方法
5). Python中没有像C++中 public 和 private 这些关键字来区别公有属性和私有属性。
6). Python是以属性命名方式来区分,如果在属性和方法名前面加了2个下划线'__',则表明该属性和方法是私有权限,否则为公有权限。

————————————————————————————————————————————————————————————————————
class Teacher(object):
__money=1
def __init__(self):
self.a=1
def study(self):
print('学习的方法')
def earn(self):
print('挣钱的方法')
@classmethod
def gai(cls):
cls.__money=2
print(cls.__money)
class Student(Teacher):
def __init__(self):
self.a=2
def earn(self):
print('挣钱的方法2')
def q(self):
Teacher.earn(self)
def w(self):
Teacher.__init__(self)
print(self.a)
student=Student()
student.q()
student.w()


挣钱的方法
1
————————————————————————————————————————————————————————————————————