# 定义一个学生类,用来形容学生
class Student():
pass # 只是占位,没有任何意义,且必须写
mingyue = Student()
class PythonStudent():
name = None
age = 18
course = "Python"
def doHomeWork(self):
print("在做作业!")
return None
yueyue = PythonStudent() # 实例化一个学生
print(yueyue.name)
print(yueyue.age)
yueyue.doHomeWork()
实例化类
变量 = 类名() # 实例化了一个类
访问成员对象
使用点操作符
obj.成员属性名称
obj.成员方法
可以通过默认内置变量检查类和对象的所有成员
对象所有成员检查
obj.__dict__
# dict前后各两个下划线
类所有成员
class_name.__dict__
class A():
name = "jiujiu"
age = 18
A.__dict__
>>>
mappingproxy({'__module__': '__main__',
'name': 'jiujiu',
'age': 18,
'__dict__': <attribute '__dict__' of 'A' objects>,
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'__doc__': None})
class A():
name = "jiujiu"
age = 18
def say(self):
self.name = "baba"
self.age = 19
print(A.name) # A称为类实例
print(A.age)
print(id(A.name))
print(id(A.age))
a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
## 说明:类实例的属性和其对象的实例的属性在不对对象的实例属性赋值的前提下,指向同一个变量
>>>
jiujiu
18
2412651057928
140719419683104
jiujiu
18
2412651057928
140719419683104
class Student():
name = "dana"
age = 19
def say(self):
self.name = "yaona"
self.age = 17
print("My name is {0}".format(self.name))
print("My age is {0}".format(self.age))
def sayAgain(): # 没有self
print("nice to see you again")
s = Student()
s.say()
Student.sayAgain() # 只能通过类这样访问,对象访问报错如下
s.sayAgain()
>>>
My name is yaona
My age is 17
nice to see you again
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-e8f7fdbe1bcb> in <module>()
14 s.say()
15 Student.sayAgain()
---> 16 s.sayAgain()
TypeError: sayAgain() takes 0 positional arguments but 1 was given
class Student():
name = "dana"
age = 19
def say(self):
self.name = "yaona"
self.age = 17
print("My name is {0}".format(self.name))
print("My age is {0}".format(self.age))
def sayAgain():
print(__class__.name) #
print(__class__.age) #访问类成员
print("nice to see you again")
s = Student()
s.say()
Student.sayAgain()
>>>
My name is yaona
My age is 17
dana
19
nice to see you again
class A():
name = "dana"
age = 18
def __init__(self):# 这是构造函数
self.name = "aaaaa"
self.age = 200
def say(self):
print(self.name)
print(self.age)
class B():
name = "bbbb"
age = 89
a = A()
a.say() # 此时,系统会默认把a作为第一个参数传入函数
# A.say() 这个会报错,因为say函数要默认传入一个对象,但是A是一个类,因此函数就缺少参数而报错
A.say(a) # 此时手动传入一个参数a
A.say(A) # 此时A会被手动传入
A.say(B) # 此时B被手动传入
# 上面这个叫做鸭子模型:不管是不是鸭子,只要具有鸭子的一些特征,就认为是鸭子
>>>
aaaaa
200
aaaaa
200
dana
18
bbbb
89
class Person():
name = "dana" # 这是共有的
__age = 18 # 这是私有的
p = Person()
print(p.name)
print(p.__age) # 报错
>>>
dana
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-34-052c55c92458> in <module>()
5 p = Person()
6 print(p.name)
----> 7 print(p.__age) # 报错
AttributeError: 'Person' object has no attribute '__age'
# name mangling技术
print(Person.__dict__)
# 还是可以访问到的,如下
p._Person__age = 90
print(p._Person__age)
>>>
{'__module__': '__main__', 'name': 'dana', '_Person__age': 18, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
90
# 在python中任何一个类都有一个父类object
class Person():
name = "dana"
age = 10
def sleep(self):
print("sleeping......")
# 父类写在括号中
class Teacher(Person):
pass
t = Teacher()
print(t.name)
print(Teacher.name)
>>>
dana
dana
class Person():
name = "dana"
__score = 0
age = 10
_petname = "sec"
def sleep(self):
print("sleeping......")
def work(self):
print("make some money")
class Teacher(Person):
name = "yaona"
def doTest(self):
print("exam exam ...")
def work(self):# 扩充父类的功能
# 调用父类的功能,
# Person.work(self)
# 另一种方法
super().work()
self.doTest()
t = Teacher()
print(t.name)
t.doTest()
t.work()
>>>
yaona
exam exam ...
make some money
exam exam ...
class Animel():
def __init__(self):
print("Animel ...")
class PaxingAni(Animel):
def __init__(self, name):
print("pa xing dong wu {}".format(name))
class Dog(PaxingAni):
def __init__(self):
# PaxingAni.__init__(self) 这可以调用父类的构造函数
# super(PaxingAni, self).__init__() 同上
print("wang wang ....")
class Cat(PaxingAni):
pass
kaka = Dog() # 狗有自己的构造函数,就不往上查找构造函数
caca = Cat() # 猫没有自己的构造函数,则往上查找构造函数,这里报错,因为PaxingAni需要两个参数,实例化时只给里一个
>>>
wang wang ....
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-c5d20a992e9f> in <module>()
15
16 kaka = Dog()
---> 17 caca = Cat()
TypeError: __init__() missing 1 required positional argument: 'name'
class A():
pass
class B(A):
pass
print(A.__mro__)
print(B.__mro__)
>>>
(<class '__main__.A'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
class Fish():
def __init__(self, name):
self.name = name
def swim(self):
print("swimming..........")
class Bird():
def __init__(self, name):
self.name = name
def fly(self):
print("flying.......")
class Person():
def __init__(self, name):
self.name = name
def work(self):
print("working......")
class SuperMan(Person, Bird, Fish):
def __init__(self, name):
self.name = name
s = SuperMan("yueyue")
s.work()
s.swim()
s.fly()
>>>
working......
swimming..........
flying.......
class Person():
name = "dana"
age = 18
def eat(self):
print("Eatting.......")
def drink(self):
print("Drinking......")
def sleep(self):
print("Sleeping.......")
class Teacher(Person):
def work(self):
print("Working......")
class Student(Person):
def study(self):
print("Studying......")
class Tutor(Teacher, Student):
pass
t = Tutor()
print(Tutor.__mro__)
print(t.__dict__)
print(Tutor.__dict__)
class TeacherMixin(): # Mixin不需要继承父类,只是一个功能的拓展
def work(self):
print("Working......")
class StudentMixin():
def study(self):
print("Studying......")
class TutorM(Person, TeacherMixin, StudentMixin):
pass
tt = TutorM()
print(TutorM.__mro__)
print(tt.__dict__)
print(TutorM.__dict__)
>>>
(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
class A():
name = "noName"
class B(A):
pass
class C():
pass
print(issubclass(B, A))
print(issubclass(C, A))
a = A()
print(isinstance(a, A))
print(hasattr(a, "name"))
print(hasattr(a, "age"))
>>>
True
False
True
True
False
class Person():
def fget(self):
return self._name
def fset(self,name):
self._name = name.upper()
def fdel(self):
self._name = "NoName"
name = property(fget, fset, fdel, "对name进行操作!")
p = Person()
p.name = "dana"
print(p.name)
>>>
DANA
__dict__:以字典的方式显示类的成员属性
__doc__:显示类的说明文档
__name__:获取类的名称
__bases__:显示类的所有父类
class A():
def __init__(self):
print("我被调用了")
def __call__(self):
print("我有被调用了again")
def __str__(self):
return "我是字符串"
a = A()
a()
print(a)
>>>
我被调用了
我有被调用了again
我是字符串
class Person():
def __init__(self):
pass
def __setattr__(self, name, value):
print("设置属性:{0}".format(name))
# self.name = value 这种会直接死循环
super().__setattr__(name,value) # 为了避免死循环,规定统一调用父类魔法函数
p = Person()
print(p.__dict__)
p.age = 19
>>>
{}
设置属性:age
class Person():
# 实例方法
def eat(self):
print(self)
print("eating.....")
# 类方法
# 类方法的第一个参数,一般命名为cls,区别于self
@classmethod
def play(cls):
print(cls)
print("playing.......")
# 静态方法
# 不需要用第一个参数表示自身或者类
@staticmethod
def say():
print("saying....")
yueyue = Person()
# 实例方法
yueyue.eat()
# 类方法
Person.play()
yueyue.play()
# 静态方法
Person.say()
yueyue.say()
>>>
<__main__.Person object at 0x00000210C2FD2B00>
eating.....
<class '__main__.Person'>
playing.......
<class '__main__.Person'>
playing.......
saying....
saying....
# 抽象类的实现
import abc
# 声明一个类并且指定当前类的元类
class Human(metaclass = abc.ABCMeta):
# 定义一个抽象方法
@abc.abstractmethod
def smoking(self):
pass
# 定义类抽象方法
@abc.abstractclassmethod
def drink():
pass
# 定义静态抽象方法
@abc.abstractstaticmethod
def play():
pass
class A():
pass
def say(self):
print("Saying ... ... ..")
class B():
def say(self):
print("saying.........")
say(9)
A.say = say
a = A()
a.say()
>>>
Saying ... ... ..
Saying ... ... ..
from types import MethodType
class A():
pass
def say(self):
print("Saying ... ... ..")
a = A()
# a.say = say 实例不能和方法直接组装,必须如下
a.say = MethodType(say, A)
a.say()
>>>
Saying ... ... ..
# type造类
def say(self):
print("saying.... ... ..")
def talk(self):
print("talking.... ... ..")
A = type("AName", (object,), {"class_say":say, "class_talk":talk})
a = A()
a.class_say()
a.class_talk()
>>>
saying.... ... ..
talking.... ... ..
# 元类的写法固定,必须继承自type
class TMethodClass(type):
def __new__(cls,name,bases,attrs):
print("hahah,我是元类")
attrs['id'] = '000000'
attrs['addr'] = 'shiyanshi'
return type.__new__(cls, name, bases, attrs)
# 元类定义完就可以使用,使用注意写法
class Teacher(object, metaclass=TMethodClass):
pass
t = Teacher()
print(t.id)
>>>
hahah,我是元类
000000