Foundation of Python: classes in Python

Alibaba cloud technology blog 2021-04-06 17:45:49
foundation python classes python

brief introduction : class It's a very important concept in object-oriented programming ,python There are also class, All standard programming features are supported : Inherit , Polymorphism etc. . This article will explain in detail Python in class Information about .

brief introduction

class It's a very important concept in object-oriented programming ,python There are also class, All standard programming features are supported : Inherit , Polymorphism etc. .

This article will explain in detail Python in class Information about .

Scope and namespace

In the detailed explanation class Before , Let's look at the concept of scope and namespace .

Namespace (Namespace) It's a mapping from name to object , Most of the namespace is through Python Dictionary to achieve .

The main purpose of a namespace is to avoid name conflicts in a program . As long as the name remains unique in the same namespace , Names in different command spaces don't affect each other .

Python There are three kinds of namespace in :

  • Built in name (built-in names), Python Language built-in names , Like the function name abs、char And exception name BaseException、Exception wait .
  • Global name (global names), The name defined in the module , Module variables recorded , Include function 、 class 、 Other imported modules 、 Module level variables and constants .
  • Local name (local names), The name defined in the function , The variables of the function are recorded , Including parameters of functions and locally defined variables .( Class is also defined in )

The search order for the namespace is Local name -》 Global name -》 Built in name .

Namespaces created at different times have different lifetimes . The namespace containing the built-in name is in Python Created when the interpreter starts , It will never be deleted . The global namespace of a module is created when the module definition is read in .

Usually , The module namespace will also persist until the interpreter exits .

The statement executed by the top-level call of the interpreter , For example, a program that reads from a script file or interactively , Is considered to be __main__ Part of the module call , So they also have their own global namespace .( The built-in name actually exists in a module ; This module is called builtins .)

One Scope Is a namespace directly accessible Python The text area of the program .

Python There are four scopes in :

  • Local: The innermost layer , Contains local variables , Like a function / Methods the internal .
  • Enclosing: Contains nonlocal (non-local) It's not the whole picture (non-global) The variable of . Like two nested functions , A function ( Or class ) A It contains a function B , So for B For the name of A The scope in is nonlocal.
  • Global: The outermost layer of the current script , For example, the global variables of the current module .
  • Built-in: Contains built-in variables / Keywords, etc ., It was finally searched

The search order for scopes is Local -> Enclosing -> Global -> Built-in

Python of use nonlocal The keyword is declared as Enclosing Range , use global Keyword declared as global scope .

Let's take a look at one global and nonlocal Examples of how variable binding can be affected :

def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
print("After local assignment:", spam)
print("After nonlocal assignment:", spam)
print("After global assignment:", spam)
print("In global scope:", spam)

The above program outputs :

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

The variables in the function default to local Scope , If you want to modify the variables of the external function in the function of the function , Then you need to declare this variable as nonlocal, Finally, the variables at the top level of the module or program file are global scope , If you need to modify the reference, you need to declare it as global Scope .


Python The class in is used to class To define the , Let's look at the simplest class Definition :

class ClassName:

The code in the class definition creates a new namespace , The variables inside are considered local scopes . All assignments to local variables are in this new namespace .

Class object

class After defining the class , A class object is generated . We can use this class object to access the properties and methods defined in the class .

For example, we define the following class :

class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'

Class defines a property i And a way f. Then we can pass MyClass.i and MyClass.f Come and visit them .

Be careful ,Python There is no such thing as java Medium private,public This kind of variable access scope control . You can take Python class The variables and methods in are seen as public Of .

We can go directly to MyClass.i Assign values to change i The value of the variable .

In [2]: MyClass.__doc__
Out[2]: 'A simple example class'
In [3]: MyClass.i=100
In [4]: MyClass
Out[4]: __main__.MyClass
In [5]: MyClass.i
Out[5]: 100

Class in , We also defined class Documents , You can go directly through __doc__ To visit .


Instantiate a class object , You can think of a class as a parameterless function .

In [6]: x = MyClass()
In [7]: x.i
Out[7]: 100

Above we created a MyClass Example , And assigned to x.

By visiting x Medium i value , We can find this i The value is and MyClass In class variables i The values are consistent .

Instantiation operation (“ call ” Class object ) Will create an empty object . If you want to do some custom operations when instantiating , Then you can define a __init__() When the method is used , The instantiation operation of the class will automatically initiate a call for the newly created class instance __init__().

def __init__(self): = []

__init__() Methods can also take parameters , These parameters are passed in when we instantiate the class :

>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

Properties of an instance object

Or above class, We define a i Properties and a f Method :

class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'

We can access this property through instance objects :

In [6]: x = MyClass()
In [7]: x.i
Out[7]: 100

We can even create a property in an instance object that does not belong to a class object :

In [8]: x.y=200
In [9]: x.y
Out[9]: 200

Even after use , Don't keep any records :

x.counter = 1
while x.counter < 10:
x.counter = x.counter * 2
del x.counter

Method object

We have two ways to access methods defined in functions , One is through class objects , One is through instance objects , Look at the difference between the two :

In [10]: x.f
Out[10]: <bound method MyClass.f of <__main__.MyClass object at 0x7fb69fc5f438>>
In [11]: x.f()
Out[11]: 'hello world'
In [12]: MyClass.f
Out[12]: <function __main__.MyClass.f>
In [13]: MyClass.f()
TypeError Traceback (most recent call last)
<ipython-input-13-e50d25278077> in <module>()
----> 1 MyClass.f()
TypeError: f() missing 1 required positional argument: 'self'

From the output above, we can see that ,MyClass.f It's a function , and x.f It's a object object .

Remember f Definition of method ?f There is one method self Parameters , If called as a function , You must pass in all the required parameters , That's why it's called directly MyClass.f() Report errors , and x.f() The reason why it can run directly .

Although the first parameter of a method is often named self. This is just an agreement : self The name is in Python There is absolutely no special meaning in .

The special thing about the first method that is passed as an object parameter is that it's called an object . In our example , call x.f() It's the same thing as MyClass.f(x). All in all , Call a with n A method with one parameter is equivalent to calling the corresponding function with another parameter , The value of this parameter is the instance object to which the method belongs , Position before other parameters .

Why method objects don't need to be passed in self What about this parameter ? from x.f We can see that , This method is already bound to an instance object , therefore self Parameters are automatically passed in .

Method can be used by self Parameter to call other methods :

class Bag:
def __init__(self): = []
def add(self, x):
def addtwice(self, x):

Class variables and instance variables

In the use of class variables and instance variables , What problems should we pay attention to ?

Generally speaking , Instance variables are used for unique data for each instance , Class variables are used for properties and methods shared by all instances of a class .

class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name): = name # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
>>> e.kind # shared by all dogs
>>> # unique to d
>>> # unique to e

therefore , If it's an instance variable , Then you need to assign and initialize in the initialization method . If it's a class variable , It can be defined directly in the structure of a class .

An example of using instance variables correctly :

class Dog:
def __init__(self, name): = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']

If the same property name appears in both instances and classes , Then the attribute lookup takes precedence over the instance :

>>> class Warehouse:
purpose = 'storage'
region = 'west'
>>> w1 = Warehouse()
>>> print(w1.purpose, w1.region)
storage west
>>> w2 = Warehouse()
>>> w2.region = 'east'
>>> print(w2.purpose, w2.region)
storage east


look down Python The inherited syntax in :

class DerivedClassName(BaseClassName):

If the base class is defined in another module :

class DerivedClassName(modname.BaseClassName):

If the requested property cannot be found in the class , The search will go to the base class to find . If the base class itself is derived from some other class , Then this rule will be applied recursively .

Derived classes may override the methods of their base classes . Because methods do not have special permissions when calling other methods of the same object , So a base class method that calls another method defined in the same base class may eventually call a method that covers its derived class .

Python There are two built-in functions that can be used to easily determine whether it is an inheritance or an instance :

  • Use isinstance() To check the type of an instance : for example :isinstance(obj, int) Only in the obj.__class__ by int Or one derived from int Similar to True.
  • Use issubclass() To check the inheritance relationship of the class :
    for example : issubclass(bool, int) by True, because bool yes int Subclasses of . however ,issubclass(float, int) by False, because float No int Subclasses of .

Python Multiple inheritance is also supported :

class DerivedClassName(Base1, Base2, Base3):

If a property is in DerivedClassName No , Then it will arrive Base1 Search for it , then ( recursively ) To Base1 Search for , If you can't find it there , Until then Base2 Mid search , And so on .

Private variables

although Python There is no mandatory syntax for private variables in , But most Python The code follows such a convention : Name with an underscore ( for example _spam) It should be taken as API The non-public part of ( Whether it's a function 、 Method or data member ).

It's just that we're writing Python An implementation detail of the program , It's not a mandatory specification of grammar .

Since there are private variables , Then in the case of inheritance, it is possible to have private variable coverage ,Python How to solve it ?

Python You can avoid the private variable's coverage by rewriting the variable name .

In any form __spam Identifier ( Underline with at least two prefixes , At most one suffix underline ) The text of will be replaced with _classname__spam, among classname For the current class name without prefix underscores . This rewriting does not take into account the syntactic position of the identifier , As long as it appears inside the class definition, it will do .

for instance :

class Mapping:
def __init__(self, iterable):
self.items_list = []
def update(self, iterable):
for item in iterable:
__update = update # private copy of original update() method
class MappingSubclass(Mapping):
def update(self, keys, values):
# provides new signature for update()
# but does not break __init__()
for item in zip(keys, values):

The above example even in MappingSubclass Introduced a __update There is no error in the case of identifiers , Because it will be in Mapping Class is replaced with _Mapping__update And in the MappingSubclass Class is replaced with _MappingSubclass__update.

Please pay attention to pass it on to exec() or eval() The code will not consider the class name of the calling class as the current class ; This is similar to global The effect of the statement , So this effect is limited to code that is compiled in bytecode at the same time .


For most container objects , have access to for Statement to traverse the elements in the container .

for element in [1, 2, 3]:
for element in (1, 2, 3):
for key in {'one':1, 'two':2}:
for char in "123":
for line in open("myfile.txt"):
print(line, end='')

The underlying principle is for Statement is called on the container object iter() Method . This function returns a definition __next__() Iterator object for method , This method will access the elements in the container one by one . When the elements are exhausted ,__next__() Will lead to StopIteration Exception to notify termination for loop .

You can use next() Built in function to call __next__() Method ; The following example shows how to use it :

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
>>> next(it)
>>> next(it)
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>

After knowing the principle of iterators , We can customize it for class Add iterator object , We need to define one __iter__() Method to return a __next__() Object of method . If the class already defines __next__(), be __iter__() You can simply go back to self:

class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data): = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1


generator Is a simple and powerful tool for creating iterators . They are written like standard functions , But when they want to return data, they use yield sentence . Every time you call on the generator next() when , It will resume execution from where it left last time ( It remembers all the data values from the last statement execution ).

Look at an example of a generator :

def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
>>> for char in reverse('golf'):
...  print(char)

What can be done with generators can also be done with the class based iterators described in the previous section . But the generator is more compact , Because it will automatically create __iter__() and __next__() Method .

The generator can also be executed in the form of expression code , This is similar to the list derivation , But the outer layer is parentheses, not square brackets .

>>> sum(i*i for i in range(10)) # sum of squares
>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
>>> unique_words = set(word for line in page for word in line.split())
>>> valedictorian = max((student.gpa, for student in graduates)
>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']

This article has been included in

The most popular interpretation , The deepest dry goods , The most concise tutorial , There are so many tricks you don't know about waiting for you to discover !

Welcome to my official account. :「 Program those things 」, Know technology , Know you better !

This article is the original content of Alibaba cloud , No reprint without permission .


本文为[Alibaba cloud technology blog]所创,转载请带上原文链接,感谢

  1. 商业数据分析从入门到入职(7)Python基础数据结构及其操作
  2. 商业数据分析从入门到入职(6)Python程序结构和函数
  3. Business data analysis from entry to entry (9) Python Network Data Acquisition
  4. Business data analysis from entry to entry (8) Python module, file IO and object oriented
  5. Business data analysis from entry to entry (7) Python basic data structure and its operation
  6. Business data analysis from entry to entry (6) Python program structure and function
  7. 简简单单实现 Python Web 的登录注册页面,还包含一半逻辑。
  8. Simple implementation of Python web login registration page, but also contains half of the logic.
  9. 什么是pip?Python新手入门指南
  10. What is PIP? Getting started with Python
  11. Python uses for... Else to jump out of double nested loop
  12. Python基础之:Python中的内部对象
  13. 人工智能入门:Python实现机器学习
  14. The foundation of Python: inner objects in Python
  15. Introduction to artificial intelligence: machine learning in Python
  16. Python基础之:Python中的内部对象
  17. The foundation of Python: inner objects in Python
  18. Python 小技之 Office 文件转 PDF
  19. 还在为多张Excel汇总统计发愁?Python 秒处理真香!
  20. 用 Python 制作音乐聚合下载器
  21. Spark Delta Lake 0.4.0 发布,支持 Python API 和部分 SQL
  22. How to transfer office files to PDF
  23. Are you still worried about multiple excel summary statistics? Python second processing really fragrant!
  24. Making music aggregate downloader with Python
  25. Spark delta Lake 0.4.0 is released, supporting Python API and part of SQL
  26. Python信息搜集
  27. Python information gathering
  28. Python - 关于类(self/cls) 以及 多进程通讯的思考
  29. Python - thinking about class (self / CLS) and multi process communication
  30. Python - 关于类(self/cls) 以及 多进程通讯的思考
  31. Python - thinking about class (self / CLS) and multi process communication
  32. Python信用评分卡建模(附代码)
  33. Python credit score card modeling (with code)
  34. 学Python需要学数据库吗?Python学习教程!
  35. Do you need to learn database to learn Python!
  36. Python私有变量如何定义?Python学习教程!
  37. How to define Python private variables? Python tutorial!
  38. Python数据分析入门(六):Pandas的函数应用
  39. Introduction to Python data analysis (6): function application of pandas
  40. 学Python需要学数据库吗?Python学习教程!
  41. Do you need to learn database to learn Python!
  42. Python描述 LeetCode 80. 删除有序数组中的重复项 II
  43. C++/python描述 AcWing 94. 递归实现排列型枚举
  44. C++/python描述 AcWing 92. 递归实现指数型枚举
  45. Python描述 LeetCode 88. 合并两个有序数组
  46. 苏州大学计算机考研 复试机试真题2013-2021真题及Python题解
  47. Python描述 LeetCode 781. 森林中的兔子
  48. 字典和json的区别是什么?Python学习
  49. Python describes leetcode 80. Removing duplicate items from ordered arrays II
  50. C + + / Python description acwing 94. Recursive implementation of permutation enumeration
  51. C + + / Python description acwing 92. Recursive implementation of exponential enumeration
  52. Python describes leetcode 88. Merging two ordered arrays
  53. Real computer test questions 2013-2021 of computer postgraduate entrance examination of Soochow University and python solutions
  54. The rabbit in the forest
  55. Python中的魔法属性
  56. What's the difference between dictionary and JSON? Python learning
  57. Magic properties in Python
  58. 字典和json的区别是什么?Python学习
  59. What's the difference between dictionary and JSON? Python learning
  60. python刷题-字母图形