没有文字描述,因为图足够好!
- 查看一个类的基类可以使用
__bases__
方法 - 查看一个实例对应的类是谁,可以用
__class__
方法
class Animal:
pass
class User:
pass
class Dog(Animal, User):
pass
if __name__ == "__main__":
print(Dog.__bases__) # (<class '__main__.Animal'>, <class '__main__.User'>)
print(User.__bases__) # (<class 'object'>,)
print(int.__bases__) # (<class 'object'>,)
print(float.__bases__) # (<class 'object'>,)
print(bool.__bases__) # (<class 'int'>,)
print(object.__bases__) # ()
class User:
pass
u = User()
print(u.__class__) # <class '__main__.User'>
# Python万物皆对象,类本质也是个对象,所以肯定也是由另外的类创建出来的
print(User.__class__) # <class 'type'>
print(type.__class__) # <class 'type'>
print(type.__bases__) # <class 'type'>
这里补充一下type的常见用法吧:
- type()可以用来创建类
- 还可以自定义元类
# 这个函数用来动态的创建类对象
# 这就是动态语言的特性,在Python中实现是非常简单的,而在Java中是很难的
# 但是这样去写代码还是复杂的,因为还是需要我们去定义class语句
def create_class(name):
if name == "user":
class User:
def __str__(self):
return "user"
return User
if name == "company":
class Company:
def __str__(self):
return "company"
return Company
if __name__ == "__main__":
MyClass = create_class("user")
my_obj = MyClass()
print(my_obj) # user
# 使用type动态的灵活的创建类,不用去写class语法
if __name__ == "__main__":
# 类的名字是User,()代表不继承任何基类,{}代表类属性为空
User = type("User", (), {})
my_obj1 = User()
print(my_obj1) # <__main__.User object at 0x108861700>
Company = type("Company", (), {"name":"cop"})
my_obj2 = Company()
print(my_obj2.name) # cop
print(Company.__dict__) # {'name': 'cop', ...}
# 使用type动态的灵活的创建类,且定义一些方法
def say(self):
return self.name
def see(cls):
return cls.name
if __name__ == "__main__":
User = type("User", (), {"name": "class_name", "say": say, "see": classmethod(see)})
my_obj = User()
print(my_obj.say()) # class_name
print(
User.__dict__,
) # {'name': 'class_name', 'say': <function say at 0x10aa7b0d0>, 'see': <classmethod object at 0x10abfafd0>, ...}
print(User.see()) # class_name
# 使用type动态的灵活的创建类,且继承一些基类
class BaseClass:
def answer(self):
return "I am BaseClass"
if __name__ == "__main__":
# 注意元组中只有一个元素是一定要加逗号的
User = type("User", (BaseClass,), {})
my_obj = User()
print(my_obj.answer()) # I am BaseClass
# 这是个自定义元类的demo
# 用于创建一个类时,自动将类中的方法名改为大写
# 例如:User中的方法名say,将被改为SAY
# 用法:在类中添加metaclass=UpperAttrMetaclass即可
# 例如:class User(metaclass=UpperAttrMetaclass):
# 如果我们需要自定义元类就需要继承自type
class UpperAttrMetaclass(type):
"""自定义元类的目的就是为了控制User类实例化的过程"""
def __new__(cls, *args, **kwargs):
"""
args: 是个tuple类型,和type(name, bases, dict)的写法是一样的,你可以在type类的源码中看到这样的写法
"""
print("*" * 50)
name = args[0] # User
bases = args[1] # (<class '__main__.A'>,)
dct = args[2] # {'__module__': '__main__', '__qualname__': 'User', '__doc__': '...', '__init__': <function User.__init__ at 0x106f120d0>, 'say': <function User.say at 0x106f12160>}
kwds = kwargs # {},这里始终为空
print(name, bases, dct, kwds, sep="\n", end="\n" + "*" * 50 + "\n")
uppercase_attr = {}
for name, value in dct.items():
if not name.startswith("__"):
uppercase_attr[name.upper()] = value
else:
uppercase_attr[name] = value
return super().__new__(cls, name, bases, uppercase_attr, **kwds)
class A:
"""没有任何意义,只是为了让上面自定义元类的bases参数打印不为空,便于理解而已"""
pass
class User(A, metaclass=UpperAttrMetaclass):
"""这样就指明当我们创建User类的时候使用的元类是UpperAttrMetaclass"""
def __init__(self, name):
self.name = name
def say(self):
print(f"i am {self.name}")
print(hasattr(User, "say")) # False
print(hasattr(User, "SAY")) # True
f = User("foo")
print(f) # <__main__.User object at 0x106f16760>
f.SAY() # i am foo
# f.say() # AttributeError: 'User' object has no attribute 'say'
print(f.__dict__) # {'name': 'foo'}
print(
User.__dict__,
) # {'__init__': <function User.__init__ at 0x106f120d0>, 'SAY': <function User.say at 0x106f12160>, ...}